Page inside UWP SplitView control has a limit to its Width - win-universal-app

As described in this GitHub issue (https://github.com/eloekset/UWPSplitViewIssue/issues/1) I try to make an UWP calculator app that can be as tiny as the built-in calculator in Windows 10. However after adding a SplitView control to get a hamburger button and a side pane menu, the Page hosted inside the SplitView.Content cannot be any narrower than 320 pixels.
I find that odd, as the built-in calculator clearly can be as small as 202x357 pixels, while it also has a hamburger button and a side pane menu. I assume it is built using the same SplitView control as all UWP apps have access to, so I must be doing something wrong.
To demonstrate the problem, I've created a simple project with the same issue and published it on GitHub: https://github.com/eloekset/UWPSplitViewIssue

You can make the window smaller by using SetPreferredMinSize in the app's OnLaunched method.
Here is an example
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
...
var applicationView = ApplicationView.GetForCurrentView();
applicationView.SetPreferredMinSize(new Size { Width = 202, Height = 357 });
Window.Current.Activate();
}
The smallest allowed size is 192x48 EP (Effective Pixels). See here for more information.
As far as the SplitView.Content region goes, I've inspected the Template and do not see anything that would restrict it's minimum size with the exception of the Pane's ColumnDefinition
Here is the snippet from the extracted SplitView Template:
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition1"
Width="{Binding TemplateSettings.OpenPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<ColumnDefinition x:Name="ColumnDefinition2"
Width="*" />
</Grid.ColumnDefinitions>
I notice the ColumnDefinition1 that is using Binding TemplateSettings.OpenPaneLength, after testing OpenPaneLength="0" it seems to respect the content.
Here is the debug output I got using your GitHub repo after setting OpenPaneLength to 0
Page Width: 202 and Height: 464
ContentFrame Width: 202 and Height: 464
Smallest there is.

Related

ScrollViewer is not working inside FlipView

I have been working around to find out solution for scrolling inside FlipView, however, the scrolling is not working properly. I am using SplitView template in my page and I have put FlipView inside Frame.
<Frame>
<FlipView ItemsSource="{Binding QuranPages}"
SelectedItem="{Binding QuranPageSelectedItem, Mode=TwoWay}"
Padding="20" FlowDirection="RightToLeft">
<FlipView.ItemTemplate>
<DataTemplate>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Image Stretch="UniformToFill"
Source="{Binding PageUri}"
MaxWidth="{Binding DataContext.PageWidth, ElementName=MyPage}"
MaxHeight="{Binding DataContext.PageHeight, ElementName=MyPage}">
</Image>
</ScrollViewer>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Frame>
In Page_SizeChanged event I am updating with page size with followings;
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
{
this.model.PageWidth = Window.Current.Bounds.Width; //e.NewSize.Width-10;
this.model.PageHeight = Window.Current.Bounds.Height; //e.NewSize.Height-10;
}
I don't understand why the scroll is not working properly, though it shows the scroll viewer, but it's not scrolling.
Update 1
I have noticed that it works well with other images, but it doesn't work with these images Image 1 Image 2 Image 3
Update 2
Here I have also added the scrollviewer Image and you can see half image is appearing, the other half is not appearing while the scrollivewer is at end.
My pictures are in PNG format, do I need to change their format?
Update 3
I have added the scrollviewer with Image. The scrollviewer seems Ok, but the image is not loaded properly.
Thanks!

React Native Constant Layout on Multiple Devices

I have a minimal app with basic views, texts, images and buttons in react native. The problem I am facing, is in managing layout for multiple devices.
Any suggestions on how can I maintain a same (proportionate) view & font size for multiple devices (multiple screen resolutions and screen sizes).
View:
For example, if I want a list view of items, where each row has one image on the left, some text in between and 2 buttons on the right (one below the other i.e. flex-direction: 'column'), how can I have this look good on a 5" device as well as a 10" device?
Also, consider the buttons have some borderRadius, if we are scaling the buttons, the borderRadius value will also need to be increased. How do I achieve this?
Fonts:
I have tried using PixelRatio.getFontScale() but this scales the font depending on only the resolution (from what I understood). Using this, makes a font of size 12 look bigger on a 5" device with higher resolution and smaller on a 10" device with lower resolution. So how can I manage font sizes for the react native app?
In addition to the PixelRatio.getFontScale() you can also use the Dimensions API to get the height and width of the window, and scale your components relative to that. I have built an app that runs on both iOS and android and use this to scale width's + heights.
Checkout the link Dimensions # Facebook - React Native
ie.
Dimensions.get('window').width;
Dimensions.get('window').height;
Will return you the size of the window
How about this library? react-native-scaled-layout
You can use scaled dimensions for your layout margin, height, padding ...
(36).scaled() /* or */ (36).d()
(36).widthScaled() /* or */ (36).w()
(36).heightScaled() /* or */ (36).h()
(24).fontScaled() /* or */ (24).f()
style={{
width: (100).w(),
height: (210).h() + safeAreaBottom,
borderRadius: (16).d(),
justifyContent: 'center',
paddingBottom: safeAreaBottom + (24).h(),
}}

How to use manipulation mode to translate an image without clipping

I'm trying to create a simple application that allows the user to move an image with a TranslateTransform inside an Imagecontrol, using the ManipulationDeltaevent Handler.
However, performs the translate manipulation, the image is clipped in a weird way. In fact, it seems that it is the entire viewport which is translated instead of the image inside the viewport.
I have reproduced this behavior in this very simple application:
The code is straightforward and looks like so:
<Image
x:Name="Image"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Stretch="None"
ManipulationMode="TranslateX, TranslateY"
ManipulationStarted="Image_ManipulationStarted"
ManipulationCompleted="Image_ManipulationCompleted"
ManipulationDelta="Image_ManipulationDelta"
Source="/Assets/image.png"
>
<Image.RenderTransform>
<TranslateTransform x:Name="Translation" />
</Image.RenderTransform>
</Image>
This is the code behind:
private void Image_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Translation.X += e.Delta.Translation.X;
Translation.Y += e.Delta.Translation.Y;
}
This application displays a rectangular 600x600 plain red image. I have resized the application so that the image is way bigger than the available client area. When the user slightly moves the image in the upper left direction, this is what the application looks like:
It seems, as I explained, that the entire viewport has been translated.
If I virtually add where the image should be to the screen shot above, this is what I would have expected:
In the screenshot above, one can see that the image is taller than the application so the entire height of the client area should be covered with a red portion of the image. Likewize, since the image has been moved to the left, only a narrow portion of the right screen should be white.
I hope these screenshots help give sense to my explanations.
Please, is it possible to obtain the desired behaviour when using the ManipulationModes?
Please, is it possible to obtain the desired behaviour when using the ManipulationModes?
I think the answer is no, it's not possible to do this in an UWP app, you will need to create a desktop app to obtain the desired behaviour.
In an UWP app, the Page is in a Frame, then the controls or shapes are in the Page, so basically the controls or shapes are all in a Frame container. What you want to do is actually getting the Rectangle out from its container, in this case we need another container for this Rectangle in an UWP app.
So what I could think about for this is creating a new window to hold this Rectangle. But problems will come with this new window, the app's title is along with a new window unless this window is in the full screen mode. Obviously a full screen mode window will not solve the problem.
This function can be done with Win32 APIs, you may refer to C# Drag-and-Drop: Show the dragged item while dragging, but this APIs are not supported in an UWP app. They are for desktop app only. For example, you may refer to CreateIconIndirect function. Besides, I can't find any supported APIs for UWP app which the same functions have.

WP8 LongListSelector memory leak

I made a test application:
https://dl.dropbox.com/u/16063542/TestImageMemory.zip
It consists of three pages:
Starting page.
Page showing a list of images using ListBox
Page showing a list of images using LongListSelector
The same images, the same DataTemplate on pages 2,3:
<DataTemplate>
<Grid Height="300">
<Image local:LowProfileImageLoader.UriSource="{Binding}" />
</Grid>
</DataTemplate>
I'm using LowProfileImageLoader which everybody who developed anything for WP is aware of.
Now, I'm performing a test:
start app.
go to to a ListBoxPage and back 20 times.
Memory consumption doesn't increase and stays at appx. 50 mb level.
Then I do the same with the LongListSelector page.
App crashes on 13th navigation.
Does anybody know what is the problem?
The problem is apparently in your LowProfileImageLoader. Just throw it away and everything will work fine. I've just checked your app without it, and memory consumption doesn't get above 50 megs on LongListSelector page as well.
So far the only input from Microsoft I got on this matter: do not use WP8 LongListSelector.

Windows Store App: using XAML paths in Grid layouts (C#/XAML)

I'm starting out the design of my app by using one of the templates provided with VS2012, where you have an Image displayed next to some TextBlocks. I want the user to be able to pick a photo or similar to be the image but, in the event that they haven't done this, I want to provide a default icon.
My initial thinking was to create PNGs of the different default icons, at the different sizes that the Image icons appear at and just return those from the binding if the user hasn't specified an image, but it occurred to me that if I can use XAML Paths instead, the default icons will appear crisper because they will be drawn as vectors rather than bitmaps.
I'm not sure if that decision is a mistake but it is causing me a few headaches :-(.
The first challenge I've tried to solve is how to use binding to display either an image or the XAML Paths. My solution here was to use a Button instead of the Image, and bind Content. The Content binding returns a Canvas object that either holds the Image or the set of Paths that define the icon.
That works until I change to the snapped view, which then has smaller Image/Button elements than the unsnapped view.
So the second challenge, and the primary reason for this question, is to seek advice on how best to deal with the differing sizes of the Buttons. In the unsnapped view, the Button is 110x110. In the snapped view, the Button is 60x60. In the research I've done, the simplest way to resize the paths seems to be to use a Transform on the Canvas but since the Canvas is being returned from the Binding call, the code-behind won't necessarily know what size the parent Button is and therefore won't be able to include the Transform.
I can't use a DrawingBrush because these aren't valid in Windows Store Apps.
Is there a clean solution to this or should I go back to the simpler but slightly lower quality solution of using pre-created PNGs?
Thanks.
The solution I adopted in the end was to use two items - a button and an image - each wrapped in a border that allowed me to make only one of the items visible, depending on whether or not a bitmap image was available:
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="250" Height="250" Visibility="{Binding ImageIsAvailable, Converter={StaticResource HideIfTrue}}">
<Button Content="{Binding ImageContent}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,20,0,0" Style="{StaticResource UnstyledGraphicsButtonStyle}" Width="{Binding ImageWidth210}" Height="{Binding ImageHeight210}" Foreground="white" Padding="0" Background="Transparent" BorderBrush="{x:Null}" IsEnabled="False" />
</Border>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Visibility="{Binding ImageIsAvailable, Converter={StaticResource DisplayIfTrue}}">
<Image Source="{Binding Image250}" Stretch="{Binding Stretch250}" AutomationProperties.Name="{Binding Title}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
In this example, I'm wanting the item to be 250px by 250px. The binding for Stretch is so that I can handle images that are bigger and smaller than 250px and stretch accordingly.
For the button, the content actually comes from a declared string resource, e.g.:
<x:String x:Key="building">M13.982995,32.651007L13.982995,37.332006 18.665994,37.332006 18.665994,32.651007z M5.3319988,32.440006L5.3319988,37.332006 10.225996,37.332006 10.225996,32.440006z M34.665606,29.33198L34.665606,37.313 37.332797,37.313 37.332797,29.33198z M29.332198,29.33198L29.332198,37.340984 31.999405,37.340984 31.999405,29.33198z M13.923995,24.000005L13.923995,28.740005 18.665994,28.740005 18.665994,24.000005z M5.3319988,24.000005L5.3319988,28.839005 10.171997,28.839005 10.171997,24.000005z M34.665606,18.665992L34.665606,26.684976 37.332797,26.684976 37.332797,18.665992z M29.332198,18.665992L29.332198,26.644998 31.999405,26.644998 31.999405,18.665992z M13.331995,16.000003L13.331995,18.666003 15.998995,18.666003 15.998995,16.000003z M7.9989967,16.000003L7.9989967,18.666003 10.665997,18.666003 10.665997,16.000003z M26.665998,13.331976L39.998998,13.331976 39.998998,42.666973 26.665998,42.666973z M13.331995,10.666002L13.331995,13.332002 15.998995,13.332002 15.998995,10.666002z M7.9989967,10.666002L7.9989967,13.332002 10.665997,13.332002 10.665997,10.666002z M10.665997,0L13.331995,0 13.331995,5.3340011 15.998995,5.3340011 18.665994,10.666002 18.665994,18.666003 21.331993,18.666003 23.998992,21.332004 23.998992,42.667007 0,42.667007 0,21.332004 2.6659985,18.666003 5.3319988,18.666003 5.3319988,10.666002 7.9969978,5.3340011 10.665997,5.3340011z</x:String>
This comes from Metro Studio.
The height and width bindings are because my different SVG items have different width & height ratios so I bind to code-behind to return the correct figures for the desired size. Unfortunately because you can't pass parameters, I end up with different "ImageHeightXXX" calls for different values of XXX depending on the XAML.
Advice on how to get the string defined can be found here: http://www.jayway.com/2012/11/27/styling-windows-8-4-the-button/

Resources