In my application, I have a StackPanel with the Orientation set to 'horizontal'. In my StackPanel there are 4 Images. When I try to scroll this content horizontally, it only scrolls a few pixels and I cannot see the whole content. When I change the Orientation of my StackPanel to vertical, I can scroll my whole content vertical. Why it isn't possible to scroll it hotizontally? Any ideas how I can solve this problem?
<Grid>
<ScrollViewer>
<StackPanel Orientation="Horizontal" >
<Canvas Margin="120,0,0,0"
Width="310"
Height="390">
<Image Width="310"
Height="390"
Source="ms-appx:///Assets/Image/background_teaser.png"/>
</Canvas>
<Canvas Margin="120,0,0,0"
Width="310"
Height="390">
<Image Width="310"
Height="390"
Source="ms-appx:///Assets/Image/background_teaser.png"/>
</Canvas>
<Canvas Margin="120,0,0,0"
Width="310"
Height="390">
<Image Width="310"
Height="390"
Source="ms-appx:///Assets/Image/background_teaser.png"/>
</Canvas>
<Canvas Margin="120,0,0,0"
Width="310"
Height="390">
<Image Width="310"
Height="390"
Source="ms-appx:///Assets/Image/background_teaser.png"/>
</Canvas>
</StackPanel>
</ScrollViewer>
</Grid
Horizontal scrolling is not enabled per default.
<ScrollViewer HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Auto">
I had some issues working with Stackpanels in a ScrollViewer. Try wrapping the Stackpanel in another Grid.
And as the others have pointed out, you need to set the HorizontalScrollMode on your ScrollViewer
Related
Left:Zoomed in video (MediaElement). Right:Zoomed in picture. Same resolution. Different quality.
I want to zoom video.
It is easy with ScrollViewer and ZoomMode="true", but video is not zoom propertly (quality is worst). When I zoom snapshot from video, it is fine.
XAML code:
<Grid>
<!--Grid stuff-->
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" MinZoomFactor="1" ZoomMode="Enabled">
<MediaElement Source="Assets/gopro4k.mp4"/>
</ScrollViewer>
<ScrollViewer Grid.Column="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" MinZoomFactor="1" ZoomMode="Enabled">
<Image Source="Assets/gopro4k_00_00_03.jpg"/>
</ScrollViewer>
</Grid>
What can I do with this?
My code for moving the image control is:
<Grid Name="grid" Width="400" Height="400" ManipulationMode="All"
ManipulationDelta="Grid_ManipulationDelta_1" Margin="0,58,0,182">
<Grid.RenderTransform>
<CompositeTransform x:Name="transform" />
</Grid.RenderTransform>
<Image x:Name="Image1" Source="Assets/SmallLogo.png" Stretch="None"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
Manipulation delta has code:
private void Grid_ManipulationDelta_1(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (e.PointerDeviceType == PointerDeviceType.Touch)
{
this.transform.TranslateX += e.Delta.Translation.X;
this.transform.TranslateY += e.Delta.Translation.Y;
OutText.Text = sender.ToString();
}
else
{
e.Handled = true;
}
}
This works perfect when I move image wherever on my grid.
Now for resizing the image control I have different implementation,
<ScrollViewer x:Name="scrl2" SizeChanged="scrl_SizeChanged" ZoomMode="Enabled"
HorizontalScrollMode="Enabled" VerticalScrollMode="Enabled"
HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible"
MinZoomFactor="0.1" MaxZoomFactor="10" Margin="0" VerticalAlignment="Bottom">
<Image Source="Assets/SmallLogo.png" Stretch="None"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</ScrollViewer>
The scroll viewer can be resized here and image is child so it also can. And it changes size on runtime perfectly, but note that this is different code.
I want to implement both scenarios on image control, which seems logical, so I edit my xaml like this:
<Grid Name="grid" Width="400" Height="400" ManipulationMode="All"
ManipulationStarted="Grid_ManipulationStarted_1"
ManipulationCompleted="Grid_ManipulationCompleted_1"
ManipulationDelta="Grid_ManipulationDelta_1" Margin="0,58,0,182">
<Grid.RenderTransform>
<CompositeTransform x:Name="transform" />
</Grid.RenderTransform>
<ScrollViewer x:Name="scrl2" SizeChanged="scrl_SizeChanged"
ZoomMode="Enabled" HorizontalScrollMode="Enabled"
VerticalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
MinZoomFactor="0.1" MaxZoomFactor="10" Margin="0" VerticalAlignment="Bottom">
<Image x:Name="Image1" Source="Assets/SmallLogo.png" Stretch="None"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</ScrollViewer>
</Grid>
The RenderTransform should take care of movement and ScrollViewer should do pinch thing. But that does not work. In separate code when image is in scroll viewer only - pinch to zoom works, when image is in grid - drag to move works.
In the above code where I put image in ScrollViewer and that ScrollViewer in grid, only pinch to zoom works, movement does not work. I tried to undo the Horizontal Vertical alignment settings (set them to something null) but that is not possible. The image resizes, but remains always in the position it is set in alignment settings.
What is wrong in this implementation?
I have a FlipView which shows the pages of a leaflet as the user swipes through it. I want the user to be able to zoom in a page.
What I found so far is that if I wrap my Image inside a ScrollViewer and set ZoomMode = Enabled, the user can zoom. The strange thing is that if I zoom in the right side of the page, it automatically goes back to the left side after I lift up my fingers from the screen. Any idea how to solve this issue?
XAML:
<Grid Name="grRoot">
<FlipView x:Name="flipView1"
BorderBrush="Black"
ItemsSource="{Binding}">
<FlipView.ItemTemplate>
<DataTemplate>
<ScrollViewer ZoomMode="Enabled" MinZoomFactor="1">
<Image Source="{Binding url_dotcom}"
Stretch="Fill"
Holding="imgHolding"/>
</ScrollViewer>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Grid>
Setting the FlipView's width and height:
flipView1.Width = Window.Current.Bounds.Width;
flipView1.Height = Window.Current.Bounds.Height;
Try something like this:
<Grid Name="grRoot">
<FlipView x:Name="flipView1"
BorderBrush="Black"
ItemsSource="{Binding}">
<FlipView.ItemTemplate>
<DataTemplate>
<ScrollViewer ZoomMode="Enabled" MinZoomFactor="1"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Image Source="{Binding url_dotcom}"
Stretch="Fill"
Holding="imgHolding"
MaxWidth="{Binding ElementName=YourPage, Path=DataContext.Width}"
MaxHeight="{Binding ElementName=YourPage, Path=DataContext.Height}"/>
</ScrollViewer>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Grid>
There are 2 important changes here:
Set ScrollViewer's HorizontalScrollBarVisibility and VerticalScrollBarVisibility to Auto
Bind Image's MaxWidth and MaxHeight to Window.Current.Bounds.Width and Window.Current.Bounds.Height respectively exposed through Width and Height public properties inside a ViewModel that is a DataContext to that specific page. This is for scenarios where your FlipView is taking up the whole page. If you need the FlipView to be smaller on the page, then set the Width and Height properties in the ViewModel based on the size you expect/need/want.
EDIT:
More info in my blog post Why is my zoomable ScrollViewer snapping the image to the left?
I'm trying to scroll items in stackpanel added programmatically, but it's not working:
<ScrollViewer HorizontalScrollMode="Enabled" >
<StackPanel x:Name="options" Orientation="Horizontal" Width="760" HorizontalAlignment="Left" Margin="1,0,0,0">
</StackPanel>
</ScrollViewer>
is there any error?
You also need to specify the horizontal visibility of the ScrollViewer. Set it to any value other than Disabled (the default) and it will work:
<ScrollViewer HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Auto">
I have an image inside a border and I would like to show different parts of the image source in the image box at different times. Specifically, when a certain textbox gets focus, I want to change the image so it zooms to a certain portion of the image content.
Here's the XAML:
<Border BorderBrush="Silver" BorderThickness="1" Grid.Column="5" Height="504"
HorizontalAlignment="Left" Margin="20,116,0,0" Name="border1"
VerticalAlignment="Top" Width="410" ClipToBounds="True">
<Image Height="493" Name="image5" Stretch="Fill" Width="390"
ClipToBounds="True" BindingGroup="{Binding}"
Clip="{Binding ElementName=border1}"
Cursor="Hand" StretchDirection="Both" />
</Border>
For an example, my image source is 2550 x 3320 pixels. I would like the image box to show the source in a rectangle starting at point 1755,300 with width of 650 and height of 230. I do not want to use CloneBitmap to cut that rectangle out and display it because I also have a manual zoom set up for this image where the user can use the mouse wheel to zoom in and out and click & drag to pan the image. I still want to allow that after we zoom to desired area.
UPDATE:
I've tried implementing colinsmith's answer, but whenever I change the scrollviewer's offsets, It chops the image, so if I later move (click and drag to pan) it, it's empty space. I've had this working before with just the image inside the scrollviewer, but now I have an image inside a scrollviewer inside a border. The border is necessary for my zoom and pan as I have it set up now.
My updated XAML:
<Border BorderBrush="Silver" BorderThickness="1" Grid.Column="5" Height="504"
HorizontalAlignment="Left" Margin="20,116,0,0" Name="border1"
VerticalAlignment="Top" Width="410" ClipToBounds="True">
<ScrollViewer x:Name="image5scroll" VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden">
<Image Height="493" Name="image5" Stretch="Fill" Width="390"
ClipToBounds="True" BindingGroup="{Binding}"
Clip="{Binding ElementName=image5scroll}" Cursor="Hand"
StretchDirection="Both" />
</ScrollViewer>
</Border>
And code behind:
public void imageZoom(Element element, int index)
{
if (element.Rectangle.Left - 100 > 0)
{
image5scroll.ScrollToHorizontalOffset(element.Rectangle.Left - 100);
image5scroll.Width = element.Rectangle.Width + 200;
image5scroll.Height = element.Rectangle.Height + 200;
border1.Width = image5scroll.Width;
border1.Height = image5scroll.Height;
image5.Width = image5scroll.Width;
image5.Height = image5scroll.Height;
image5.Stretch = System.Windows.Media.Stretch.None;
}
else
{
image5scroll.ScrollToHorizontalOffset(0);
}
if (element.Rectangle.Top - 100 > 0)
{
image5scroll.ScrollToVerticalOffset(element.Rectangle.Top - 100);
}
else
{
image5scroll.ScrollToVerticalOffset(0);
}
}
You can use a ScrollViewer to wrap your Image...then you can tell the ScrollViewer to go to a vertical and horizontal offset by calling the ScrollToVerticalOffset() and ScrollToHorizontalOffset() methods (as there isn't a property which you can set).
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Border BorderBrush="Silver" BorderThickness="1" Grid.Column="5" Height="504"
HorizontalAlignment="Left" Margin="20,116,0,0" Name="border1" VerticalAlignment="Top" Width="410">
<ScrollViewer x:Name="image5scroll" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
<Image Height="493" Name="image5" Stretch="None" Width="390" BindingGroup="{Binding}"
Cursor="Hand" Source="http://www.noaanews.noaa.gov/stories/images/goes-12-firstimage-large081701.jpg"/>
</ScrollViewer>
</Border>
</Grid>
</Page>
However, if you must be be able to set the position of the ScrollViewer using properties instead of code-behind then a solution is to define an Attached Property which does the calls to ScrollToVerticalOffset/ScrollToHorizontalOffset for you underneath.
http://marlongrech.wordpress.com/2009/09/14/how-to-set-wpf-scrollviewer-verticaloffset-and-horizontal-offset/