I'm working on a C# XAML app for windows 8.1/10 and I'm having trouble creating a scrollviewer that behaves how I want.
Pretty much I want the top scroller on the default page in the Windows Store app on Windows10. It looks like this when the screen is small:
Store Scroller
It scrolls sideways through items, snaps between them, and is operated not by a scrollbar but by scrolling buttons on the side. It also has page markers at the bottom and loops through content. Ideally in mine it would also be operable with the scrollwheel on your mouse.
What I want in my UI is this:
Icon Scroller
The purpose of this control is to cycle through available options for an icon, showing exactly three at any given time; the images are selectable. I have 9 icons total so I need 3 "pages" in this scrollviewer. I've somewhat accomplished this by using a scrollpanel with a stackpanel inside which itself contains three other stackpanels for my "pages". The scrollviewer is set to snap between items and it works great. Sample code of what I've created is the following:
<ScrollViewer x:Name="scroller" HorizontalScrollBarVisibility="Hidden" VerticalScrollMode="Disabled" VerticalScrollBarVisibility="Disabled" HorizontalSnapPointsType="Mandatory" Width="120">
<StackPanel x:Name="stack_Master" Orientation="Horizontal" Height="40">
<StackPanel x:Name="stack_Page1" Orientation="Horizontal">
<Image x:Name="image_Page1_Icon1" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page1_Icon2" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page1_Icon3" Style="..." Source="..." Width="40"/>
</StackPanel>
<StackPanel x:Name="stack_Page2" Orientation="Horizontal">
<Image x:Name="image_Page2_Icon1" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page2_Icon2" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page2_Icon3" Style="..." Source="..." Width="40"/>
</StackPanel>
<StackPanel x:Name="stack_Page3" Orientation="Horizontal">
<Image x:Name="image_Page3_Icon1" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page3_Icon2" Style="..." Source="..." Width="40"/>
<Image x:Name="image_Page3_Icon3" Style="..." Source="..." Width="40"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
The pages scroll nicely with animations when using the mouse wheel. The page indicator should be easy enough to implement using some C#. My plan for the looping was to have "decoy" versions of Page3 and Page1 at the start and end of stack_Master respectively. Then once the animation finishes to programmatically change to the actual page with no animation. This would imitate a circular scroller.
The problem I'm running into is how can I implement the scrolling buttons? I don't see any methods for scrollviewers on MSDN which will change the position of the scrollviewer while maintaining the smooth animation, instead only ones that instantly change the position abruptly. If such a method existed then I could tie that to some buttons on the side of the scrollviewer.
If this method doesn't exist than I also saw a solution for when snapping isn't enabled. Essentially the button would move the scroller say 10 pixels every 50ms, simulating a flowing movement. I don't think that would be possible when snapping between pages.
It would be simple if there was a style for the scrollviewer to simply have the arrow buttons from the default scrollbar, without the actual bar between them. Does this exist?
Any help is appreciated.
Related
I have the following piece of XAML code in my WPF application,
<StackPanel DockPanel.Dock="Top" >
<TextBlock Style="{StaticResource HeaderTextBlock}">Import Log</TextBlock>
<ScrollViewer Height="400" VerticalScrollBarVisibility="Auto">
<TextBlock Name="ImportFeedBack"></TextBlock>
</ScrollViewer>
</StackPanel>
which dispalys the ImportFeedBack string (in case someone is wondering, I'm using Caliburn.Micro as MVVM framework, so that the content of the TextBlock is bound by naming convention to a property of same name in my ViewModel).
The value can vary heavily in length. I want it to use the whole available space (but it should not resize the application!), and only if that is not enough, add a vertical scroll bar.
If I delete the Height="400" in the ScrollViewer, it resizes the app for big strings, and if I leave it there, it (obviously) just uses 400 height, but ads he scroll bar when needed.
How can I get it to use all the available space, and only if that is not enough, to creata a vertical scroll bar?
Instead of StackPanel use different panel like Grid or DockPanel. In the example below second row will take all available space not allocated by first row and not expand beyond that which is when scroll bar should appear when text is longer.
<Grid DockPanel.Dock="Top" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Style="{StaticResource HeaderTextBlock}">Import Log</TextBlock>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<TextBlock Name="ImportFeedBack"></TextBlock>
</ScrollViewer>
</Grid>
I have a WPF application running on a Windows 8.1 tablet using touch. After a whole lot of reading about how to solve some common touch specific problems I found this tutorial that really pointed me in the right direction.
My problem is that after implementing the tutorial my ScrollViewer stopped working unless I scroll directly from the scroll bar itself.
this is how my ScrollViewer (which is the top element in my window) looks like:
<ScrollViewer CanContentScroll="True" PanningMode="Both">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock HorizontalAlignment="Center"
FontSize="48"
Text="{Binding SelectedView.ViewHeader}"
TextAlignment="Center"
TextWrapping="Wrap" />
<Separator Margin="0,25" />
</StackPanel>
<ContentPresenter Grid.Row="1"
Margin="10,0,0,30"
Content="{Binding SelectedView}" />
</Grid>
</ScrollViewer>
Any suggestions on how to fix it?
EDIT:
The reason I chose the method above over the one suggested above is because it eliminated many controls focus problems I was having such as textboxes the need 2 or 3 touches to receive focus or comboboxes that stay open after selecting an item:
When using this method DisableWPFTabletSupport. You are disabling all tablet support which include ScrollViewer Touch screen. See my post in this link to achieve similar behavior (show/hide windows keyboard) without disabling tablet support.
Show & hiding the Windows 8 on screen keyboard from WPF
I'm building a picture viewing app. In it I have a FlipView that shows individual images, where you can optical zoom each image. The experience is very similar to the FlipView/Optical zoom you see in the default Photos app in windows 8 (which is built using html).
I'm using a ScrollViewer for optical zoom. Optical zoom seems to be working fine except there is an odd panning behavior. You can still use a single finger to pan the image around, before it goes back to it's original position.
The photos app doesn't allow this, and I'm trying to achieve a similar behavior. Is there some way to disable panning the image around using the built in ScrollViewer control? I still want zooming in to work, but panning should be disabled. I think this should be achievable using manipulation events instead of ScrollViewer, but obviously ScrollViewer would be simpler.
<ScrollViewer x:Name="scrollViewer1" ZoomMode="Enabled" MaxZoomFactor="2.0" MinZoomFactor="1.0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Center">
<FlipView x:Name="flipView1" Width="1140" SelectionChanged="flipView1_SelectionChanged">
<FlipView.ItemTemplate>
<DataTemplate>
<Grid>
<Image x:Name="CurrentImage" Source="{Binding}" DoubleTapped="CurrentImage_DoubleTapped">
</Image>
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</ScrollViewer
You have added the FlipView to ScrollView since you must add the scrollview to flipview item template, and the image must be inside the scrollview, your xaml code must be like this:
<FlipView x:Name="flipView1" Width="1140" SelectionChanged="flipView1_SelectionChanged">
<FlipView.ItemTemplate>
<DataTemplate>
<Grid>
<ScrollViewer x:Name="scrollViewer1" ZoomMode="Enabled" MaxZoomFactor="2.0" MinZoomFactor="1.0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Center">
<Image x:Name="CurrentImage" Source="{Binding}" DoubleTapped="CurrentImage_DoubleTapped">
</Image>
</ScrollViewer>
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
I'm trying to do news app for windows store with c# and xaml..
In this project, I created a Panorama GridView like windows phone 8.. And inside of this Panorama GridView, I created small gridviews for cathegories..
Structure is like this in Document Online;
-<Grid> (whole page)
-<Grid> (Header/Logo etc.)
-<PanoramaGridView> (All cath will be under of this)
-<HotNewsGridView>
-<HotNewsGrid>
-<GroupHeaderTextBlock>
-<HotGridView>
-<SportNewsGridView>
-<PoliticsGridView>
-<GalleryGridView>
And first side of code..
<GridView x:Name="PanoramaGridView"
Grid.Row="1"
Style="{StaticResource GridViewStyle1}"
ItemContainerStyle="{StaticResource GridViewItemStyle2}">
<GridViewItem Margin="0,0,2,0" VerticalAlignment="Top">
<Grid Margin="30,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition/>
</Grid.RowDefinitions>
<GridView x:Name="HotNewsGrid"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource MansetItemTemplate}"
Grid.Row="1"
SelectionChanged="HotNewsGrid_SelectionChanged"/>
<TextBlock x:Name="GroupHeaderTextBlock"
HorizontalAlignment="Left"
Margin="0,0,-7,-18"
Grid.RowSpan="1"
TextWrapping="Wrap"
Text="Hot News"
Foreground="DarkGreen"
VerticalAlignment="Top"
Style="{StaticResource SubheaderTextStyle}"/>
</Grid>
The problem is, I cannot scroll when my mouse cursor come on the "HotNewsGrid" grid. I can only scroll from top and bottom of the application..
I think, my PanoramaGridView is okay with scrolling but when my cursor comes subgridviews (like hot news gridview) it stops scrolling, cannot scroll from it. I tried to put IsSwipeEnable, ScrollViewer.HorizontalScrollMode="Enabled" etc.. Did not worked..
I do not want scrolling the "HotNewsGrid". I just want to continue scrolling when my cursor comes on it..
I hope you understand me.. This is a very big problem for me..
Waiting your helps..
Thank you..
Add this Template to your GridView
<GridView.Template>
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
</GridView.Template>
and you will be able to scroll using a mouse.
Note that a side effect of this is that you can no longer swipe select on your GridView
I have a page like this:
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
here are contents
they are forever absolutely in the center of the screen
no matter of the resolution/size
</StackPanel>
</Grid>
Everything is working fine. But now I want to add a back button in the top-left corner.
And I don't want to split the grid into 2 columns and 2 rows like this:
the contents are no longer absolutely centered, even we can split the grid by percent, because the contents are sometimes very wide and sometimes very narrow.
I want to know how can I keep the contents horizontal/vertical aligned "Center", and then set the back button's position relatively to the content.
I would suggest using a grid layout with 3 columns to ensure the content is centered with the columns widths set to *,Auto, *. This will ensure the main content is always centered and not care about the size of the button. You can then use margins to set the seperation as required. This is a techinique I have used in SL, WPF & Metro.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Content="Do Something"/>
<ContentControl VerticalAlignment="Top" Content="My custom content"/>
</Grid>
slightly hacky ansewer
You might be able to achieve by positioning your stackpanel in the center, and then set a negative left margin the width of the button to shift everything left by the required amount...
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="-45,0,0,0">
<button with width and padding totalling 45px />
here are contents
they are forever absolutely in the center of the screen
no matter of the resolution/size
</StackPanel>
</Grid>