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>
Related
I want to add scroll view to my program and I tried ScrollView control but that don't take effect. It's my first time dealing with scrolls please help me :).
My xaml Code:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="Auto" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
Because these 2 images is not fitting here I need a scroll for them. Maybe I should use ScrollBar?
My program example: https://gyazo.com/a4ba7e4d5004632e2229a87e686c4c09
, as you can see bottom image is not fitting in range of window.
You have specified Auto as Height and Width. This implies that the Canvas will fill the height available to it.
From the documentation:
Auto sizing behavior implies that the element will fill the height
available to it.
In this case the available height is the height of the ScrollViewer.
If you want the Canvas to be bigger, and hence the ScrollViewer to scroll, you should set a height on Canvas that is bigger than the height of ScrollViewer.
So, for example:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="1000" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
If you want your ScrollViewer to work easily, use a Grid instead of a Canvas:
<DockPanel Background="#FF695887">
<ScrollViewer >
<Grid Name="zemelapis">
<Image Name="pav_kelias" Source="acteurs.png"/>
<Image Name="car1" Source="public.jpg"/>
</Grid>
</ScrollViewer>
</DockPanel>
As explain by Domysee, Canvas gives you total control of the layout. Grid however will automatically adjust its size depending on the content.
See http://www.wpf-tutorial.com/panels/introduction-to-wpf-panels/
So, I've got this mediaelement, which I want to appear in the middle of the screen, 20 pixels away from each edge, and when it's width gets to 600, it stops expanding and stays where it is. I've got the following XAML to get exactly what I want:
<Grid x:Name="video">
<MediaElement x:Name="player" AreTransportControlsEnabled="True" Margin="20,0" MaxWidth="600" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
The only problem is that the VerticalAlignment property seems to always be set to "Stretch". How can I fix this? I've tried using a viewbox, which works flawlessly, except I then get overly large or small TransportControls. I've also tried putting the mediaelement inside another grid with centered alignments, but I still get the same problem.
What you want is
20 pixels away from each edge.
But in your code you defined Margin="20,0", if you read the FrameworkElement.Margin property, you will find the useage <frameworkElement Margin="left+right,top+bottom"/>. With your code, this usage makes your MediaElement stretch in the vertical orientation.
If you use the Live Visual Tree to get a real-time view of your running XAML code, you will find, when you use the code Margin="20,0", the MediaElement is like this:
And if you use the code Margin="20", the MediaElement is like this:
The dashed red border in each picture stands for the MediaElement control.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Pivot Margin="0,0,0,0" Background="LightGray">
<PivotItem Header="Formulas">
<Grid>
<GridView HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Background="#FF983636">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<x:String>One</x:String>
<x:String>Two</x:String>
<x:String>Three</x:String>
<x:String>Four</x:String>
</GridView>
</Grid>
</PivotItem>
</Pivot>
</Grid>
The key here is HorizontalAlignment="Stretch" on the GridView.
The HorizontalAlignment="Center" on the VariableSizedWrapGrid inside the ItemsPanelTemplate inside the Gridview; should do the trick which will always keep the content centered regardless of the width of the screen.
In the end, I found how to fix this, by keeping a constant aspect ratio of 16/9:
XAML:
<Grid SizeChanged="player_SizeChanged" Background="Black" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="1" MinHeight="1" Margin="30" MaxWidth="1000" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<MediaElement x:Name="player" Margin="0">
</Grid>
C#:
private void player_SizeChanged(object sender, SizeChangedEventArgs e)
{
(sender as Grid).Height = (e.NewSize.Width * 0.5625);
}
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.
I have a ScrollViewer with an Image Control in it. It displays a rather large image. I want my user to be able to zoom into the image using gestures. I therefore enabled the ZoomMode on the Scrollviewer.
I like how display the image when it's disabled the Scrollviewer, because the image fits on the screen.
<ScrollViewer x:Name="scrollViewer" ZoomMode="Enabled"
HorizontalAlignment="Center"
VerticalAlignment="Center"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Disabled">
<Image x:Name="sketchImageView" Stretch="Uniform"
/>
</ScrollViewer>
However the Scrollviewer automatically scrolls back to the left "edge" of the image whenever the user releases its finger, making effectively zooming in and out of the image impossible.
I also tried changing the visibility to auto, but when I do this, the image is expanded and I'd like to have it fit on the screen.
You need to set the scrollbars visibility to Auto and image to UnifomToFill
<ScrollViewer x:Name="scrollViewer" ZoomMode="Enabled"
HorizontalAlignment="Center"
VerticalAlignment="Center"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Image x:Name="sketchImageView" Stretch="UniformToFill"
/>
</ScrollViewer>
I am working on a windows phone 8 app. I have a canvas containing images which I can drag to change their position in canvas. My problem is that canvas is not scrollable, I want a vertical scrollbar in page. I tried like this
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer x:Name="scvImages" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Margin="0"
HorizontalContentAlignment="Stretch" Height="Auto" Width="Auto">
<Grid Height="Auto" Width="Auto">
<Canvas x:Name="canImages" Height="Auto" Width="Auto">
</Canvas>
</Grid>
</ScrollViewer>
</Grid>
At first glance it looks like there's nothing telling the ScrollViewer to invoke since your Grid and Canvas are just going to fill the ViewPort so you might consider setting a fixed Height or something on your Grid
You must specify the height of your panel (canvas, grid, whatewer) which you want to scroll. Otherwise it will render out of the screen but 'thinks' that it is ok and scrolling is no needed (since it is infinite height).