Zoom to mouse position inside a scrollview - wpf

So I've done a ZoomControl that uses a border and an image
<UserControl x:Class="ImageViewer.Controls.ZoomControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ImageViewer.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Border x:Name="BorderImage">
<Image HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="RenderingImage" RenderTransformOrigin="0,0" Stretch="None" Source="{Binding}" RenderTransform="{Binding}"/>
</Border>
This control is nested inside a ScrollViewer
<ScrollViewer x:Name="ScollViewerImage" Grid.Column="2" Grid.Row="0" Grid.RowSpan="3" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Controls:ZoomControl x:Name="RenderingImage" ViewModel="{Binding}" ClipToBounds="True"></Controls:ZoomControl>
</ScrollViewer>
So I've built a zoom to mouse position function
private void DoZoom(double deltaZoom, Point mousePosition)
{
var scaleTransform = GetScaleTransform();
var translateTransform = GetTranslateTransform();
if (!(deltaZoom > 0) && (scaleTransform.ScaleX < .4 || scaleTransform.ScaleY < .4))
return;
var mousePositionAfterScaleX = mousePosition.X * deltaZoom;
var mousePositionAfterScaleY = mousePosition.Y * deltaZoom;
var newMousePositionX = mousePosition.X - mousePositionAfterScaleX;
var newMousePositionY = mousePosition.Y - mousePositionAfterScaleY;
var newTranslateX = newMousePositionX - mousePosition.X;
var newTranslateY = newMousePositionY - mousePosition.Y;
var translateX = newTranslateX + translateTransform.X;
var translateY = newTranslateY + translateTransform.Y;
scaleTransform.ScaleX += deltaZoom;
scaleTransform.ScaleY += deltaZoom;
_currentZoom = scaleTransform.ScaleX;
ChangeTranslateTransofrm(translateX - overflowWidth, translateY - overflowHeight);
UpdateScaleTransfromValue();
}
This works fine as long as the image fits inside the ScrollViewer size. But after the image is bigger than the ScrollVIewer control ( it shows up the scrollbars) and whenever I zoom in my mouse position is no more on the same point. I am sure it has something to do with the fact that the scrollbar are visible, but I can't figure out the math to make the mouse stick to the same position after scrollbar are visible.

So after 2 days of try and error I've found the solution for my specific problem. First of all there are 2 main problems.
Scrollbars are on auto ( they hide/show at run time based on the width.height of the child inside the ScrollViewer ). Because of that the image inside changes it's translate transform.
The scrollbar position (offset) does not persist on the same position after a zoom/in out action(child get bigger or smaller).
First problem was solved by adding 2 borders to the ScrollViewer that will keep the space needed for scrollbar occupied as long as the scrollbars are not visibile.
<ScrollViewer x:Name="ScollViewerImage" Grid.Column="2" Grid.Row="0" Grid.RowSpan="3" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Column="1" Width="{x:Static SystemParameters.VerticalScrollBarWidth}">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding ComputedVerticalScrollBarVisibility, ElementName=ScollViewerImage}"
Value="Visible">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Border Grid.Row="1" Width="{x:Static SystemParameters.HorizontalScrollBarHeight}">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding ComputedHorizontalScrollBarVisibility, ElementName=ScollViewerImage}"
Value="Visible">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Controls:ZoomControl Grid.Column="0" Grid.Row="0" x:Name="RenderingImage" ViewModel="{Binding}" ClipToBounds="True"></Controls:ZoomControl>
</Grid>
</ScrollViewer>
For the second problem whenever a scroll is done I save the offset.
I also sahve the zoom size (ScrollableHeight and Scorllable Width) and when they change (Zoom in/zoom out has been done). I reposition the scrollbar at is desired position.
private void SetScrollbarOffset(ScrollViewer scrollViewer, double verticalChange, double horizontalChange)
{
// after each move of the scrollbar we save the current offsets
_currentVerticalOffset = scrollViewer.VerticalOffset;
_currentHorizonalOffset = scrollViewer.HorizontalOffset;
// we check if there was a zoom in/out perfomed
if (_scrollableHeight != scrollViewer.ScrollableHeight)
{
// we save the current zoom in/out scrollable height
_scrollableHeight = scrollViewer.ScrollableHeight;
// we move the scrollbar to the position needed to persist the mouse under the same point in the image
scrollViewer.ScrollToVerticalOffset(_currentVerticalOffset - verticalChange);
}
if (_scrollableWidth != scrollViewer.ScrollableWidth)
{
_scrollableWidth = scrollViewer.ScrollableWidth;
scrollViewer.ScrollToHorizontalOffset(_currentHorizonalOffset - horizontalChange);
}
}
This last method is called from SizeChangedEvent
public void SizeChange(ScrollChangedEventArgs e)
{
var scrollViewer = (e.OriginalSource as ScrollViewer);
SetScrollbarOffset(scrollViewer, e.VerticalChange, e.HorizontalOffset);
}

Related

Grid column not collapsing to fit contents after width resize

I have a grid column that contains a treeview which can shrink to a width of 16 when a ToggleButton is pressed. The column is set to Width="Auto" which I assume is responsible for the shrinking behavior.
The problem is that to the right of the column, there is a grid splitter, so that the user can increase/decrease the width as they see fit. If the user does this, and then presses the ToggleButton, the contents of the column shrink to 16, but the column itself does not.
Does anyone know how I can ensure that the column shrinks in these scenarios? I'm guessing it has to do with the column width being changed from auto to a definite value, but I can't think of how to fix that once the contents shrink. Here's my code so far:
<Grid Name="ContentGrid" HorizontalAlignment="Stretch" Grid.Row="1" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" x:Name="TreeColumn"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" MinWidth="400" />
</Grid.ColumnDefinitions>
<UserControl DockPanel.Dock="Left" Grid.Row="0" Grid.Column="0" Padding="0" x:Name="TreeControl" >
<local:TreeViewControl x:Name="mainTreeView" Height="Auto" />
</UserControl>
<GridSplitter Grid.Row="0" Grid.Column="1" Margin="0,0,0,0"
Width="4" Background="Transparent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
<Grid Name="LandingPageGrid" Grid.Row="0" Grid.Column="2">
EDIT: I've tried adding a DataTrigger to the column's definition, but this hasn't worked.
<ColumnDefinition Width="Auto" x:Name="TreeColumn">
<ColumnDefinition.Style>
<Style>
<Style.Triggers>
<DataTrigger {Binding Path=IsChecked, ElementName=CollapseIcon}" Value="True">
<Setter Property="ColumnDefinition.Width" Value="Auto"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ColumnDefinition.Style>
</ColumnDefinition>
So after much debugging, many fruitless attempts, I finally resorted to setting the errant widths in the code-behind to the TreeViewControl. It's not pretty, so if someone would like to suggest a better answer, please do so, and I'll happily mark your code as the solution.
private void CollapseIcon_Checked(object sender, RoutedEventArgs e)
{
TreeControl.Width = 16;
TreeControl.HorizontalAlignment = HorizontalAlignment.Left;
((FrameworkElement) TreeControl.Parent).Width = 16;
var parentColumn = (((Grid) ((FrameworkElement) TreeControl.Parent).Parent).ColumnDefinitions)[0];
parentColumn.Width = GridLength.Auto;
}
private void CollapseIcon_Unchecked(object sender, RoutedEventArgs e)
{
TreeControl.Width = Double.NaN;
TreeControl.HorizontalAlignment = HorizontalAlignment.Stretch;
((FrameworkElement) TreeControl.Parent).Width = Double.NaN;
var parentColumn = (((Grid)((FrameworkElement)TreeControl.Parent).Parent).ColumnDefinitions)[0];
parentColumn.Width = GridLength.Auto;
}

I want to continuous display of buttons in wpf

In my application I have 4 button. If user will click on a button, that will disappear and remaining 3 still display.
The problem is that I don't want a control (button) gap between button.
I want remaining 3 should rearrange itself.
Which control I should use or how I can implement that. I am using MVVM in my application.
Button and use Visibility = Collapsed
There are multiple ways to achieve what you need. You have to be specific with you question. My way of doing this would be
xaml:
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="Button">
<EventSetter Event="Click" Handler="Button_Click"/>
</Style>
</StackPanel.Resources>
<Button Content="I am the first buttom" Margin="5"/>
<Button Content="I am the second button" Margin="5"/>
<Button Content="I am the third button" Margin="5"/>
</StackPanel >
CodeBehind:
public void Button_Click(object sender, EventArgs e)
{
(sender as Button).Visibility = Visibility.Collapsed;
}
Summary of the Solution: I would use a Grid layout with automatically expanding ColumnDefinitions (the default setting of Width="1*". When the button is clicked and disappears (Use Opacity="0"), you should change the width of the corresponding ColumnDefinition to 0.
Here are the before and after screen shots of what you want:
Before
After Click Donkey Button
After Click Bird Button
After Click Moose Button
After Click Giraffe Button(I accidentally resized before I screenshotted)
I know that you are using MVVM, but this problem is entirely in the user interface, so its encouraged to use code-behind for this solution. I don't recommend putting this type of code into mvvm.
For this solution, use a grid:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
Title="Used for question 36258073" >
<Grid>
<Grid.Resources>
<Style TargetType="Button">
<EventSetter Event="Click" Handler="AllButton_Click"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Name="ColumnDefinitionNull"/>
<ColumnDefinition Name="ColumnDefinitionOne"/>
<ColumnDefinition Name="ColumnDefinitionTwo"/>
<ColumnDefinition Name="ColumnDefinitionThree"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Name="ButtonNull" Content="Test1 Giraffe" Grid.Row="0" Grid.Column="0" />
<Button Name="ButtonOne" Content="Test2 Bird" Grid.Row="0" Grid.Column="1" />
<Button Name="ButtonTwo" Content="Test3 Donkey" Grid.Row="0" Grid.Column="2" />
<Button Name="ButtonThree" Content="Test4 Moose" Grid.Row="0" Grid.Column="3" />
</Grid>
and the code-behind for the button click is:
private void AllButton_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
button.Opacity = 0;
var zeroWidth = new GridLength(0.0);
switch (button.Name)
{
case "ButtonNull":
ColumnDefinitionNull.Width = zeroWidth;
break;
case "ButtonOne":
ColumnDefinitionOne.Width = zeroWidth;
break;
case "ButtonTwo":
ColumnDefinitionTwo.Width = zeroWidth;
break;
default:
ColumnDefinitionThree.Width = zeroWidth;
break;
}
}
The idea for the Opacity 0 came from another Stack Overflow post here. The notion about the buttons stretching in place of the other button disappearring comes from button layout and grid definition ideas this Stack Overflow post1, and this Stack Overflow post2, and this Stack Overflow post3 and this last related Stack Overflow post4.

How do I make a WPF Image control to have same dimensions as its (BitmapImage) Source?

I am designing a View in XAML, and somewhere in the layout there is an Image element, which will be put inside some combination of ViewBox, ScrollViewer and Inkcanvas (not sure about the order yet). Current early prototype is like this:
<Window x:Class="InkCanvasTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
x:Name="ThisWindow">
<DockPanel x:Name="root" DataContext="{Binding ElementName=ThisWindow}">
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Center" Margin="0,0,5,0">
<StackPanel.Resources>
<Style TargetType="{x:Type Button}" x:Key="EstiloBotão">
<Setter Property="Height" Value="40"/>
<Setter Property="Width" Value="130" />
<Setter Property="Margin" Value="5,5,0,5" />
</Style>
</StackPanel.Resources>
<Button Content="Limpar Alterações" Style="{DynamicResource EstiloBotão}"/>
<Button Content="Concluir" Style="{DynamicResource EstiloBotão}" Click="Concluir_Click" />
</StackPanel>
<!-- Magic Happens Here -->
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" PanningMode="Both" Width="752">
<InkCanvas x:Name="cv" Cursor="Cross" Width="{Binding Width, ElementName=canvas_image}" Height="{Binding Height, ElementName=canvas_image}" >
<Image x:Name="canvas_image" Stretch="Uniform" Source="C:\Users\helton\Desktop\franjas_binarizadas.png"/>
</InkCanvas>
</ScrollViewer>
</DockPanel>
</Window>
I cannot know beforehand what will be the dimensions of the source image, but I want to be sure that the Image element has its Width and Height properly "setup". The reason is that I will paint over the image (which is inside an InkCanvas element) and then save the result as an image with the same size as the source image.
Currently, my "Save" method does this:
private void Concluir_Click(object sender, RoutedEventArgs e)
{
int dWidth = (int)cv.ActualWidth; // SHOULD BE Width not ActualWidth, but is zero!!!
int dHeight = (int)cv.ActualHeight; // Here the same thing
double dpiX = 96;
double dpiY = 96;
RenderTargetBitmap rtb = new RenderTargetBitmap(dWidth, dHeight, dpiX, dpiY, PixelFormats.Pbgra32);
rtb.Render(cv);
PngBitmapEncoder pnge = new PngBitmapEncoder();
pnge.Frames.Add(BitmapFrame.Create(rtb));
Stream stream = File.Create("franjas_binarizadas_limpas.png");
pnge.Save(stream);
stream.Close();
}
THE PROBLEM: when I try to read "Width" or "Height", they are zero. When I read "ActualHeight" or "ActualWidth", sometimes they are not the value I am expecting (due to the ScrollView clipping, or the ViewBox scale layout transform).
THE GOAL: Set the Image's Width and Height properties to be equal of its Source image (via binding, or somehow else).
Any ideas?
Set the Stretch Property to None. That will make the Image control maintain the size of the original bitmap.
<Image Stretch="None"/>

WPF "tooltip" popup flickers

Long story short: I have a window that displays a bunch of charts in a ListBox. When mouseOver a chart (with LineSeries), there is a line that follows the dataPoints (snaps to the dataPoint position). Near that line I'm presenting a tooltip made from a popup that presents info about those dataPoints.
So far so good. The problem is when I try to move the mouse over the toolTip, the popup starts flickering (like its in an open/close loop). I've set already on the popup and on the children IsHitTestVisible="False".
As a temp solution the popup "goes" out of the cursors way like here:
...but is hardly "understandable".
Now comes the question: what's wrong? Why the popup starts flickering when the mouse is over it.
Any feedback welcome
PS. The tooltips XAML (it's created in code, but here it is):
The chart's datacontext is data bound to a class, also some chart's events are imlemented throught icommands. The popup is created in the constructor of that class,
ppchart = New Popup() With {.AllowsTransparency = True, .IsHitTestVisible = False,.StaysOpen = True}
...in the MouseMoveCommand the popup's child is created:
Dim ppCont As XElement = <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" IsHitTestVisible="False" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Opacity="0.5" Grid.RowSpan="2" IsHitTestVisible="False" StrokeThickness="0" RadiusX="2" RadiusY="2" Fill="#FFBABABA"/>
<TextBlock Text="{Binding Over, StringFormat=HH:mm}" FontSize="9" TextAlignment="Center" FontFamily="Segoe UI" IsHitTestVisible="False" Margin="1"/>
<ListBox x:Name="listBox" ItemsSource="{Binding Points}" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="8" Margin="1,0,1,1" Grid.Row="1" IsHitTestVisible="False" IsTextSearchEnabled="False" HorizontalAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="IsHitTestVisible" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid IsHitTestVisible="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="{Binding Culoare}" Width="3" HorizontalAlignment="Left" Margin="1" IsHitTestVisible="False"/>
<TextBlock Text="{Binding Operation}" HorizontalAlignment="Stretch" IsHitTestVisible="False" Grid.ColumnSpan="1" Grid.Column="1"/>
<TextBlock Text="{Binding points.Value}" HorizontalAlignment="Stretch" Grid.Column="2" TextAlignment="Right" IsHitTestVisible="False"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
ppchart.Effect = New Effects.DropShadowEffect() With {.Opacity = 0.5, .BlurRadius = 5, .Direction = 80, .Color = Colors.Black}
ppchart.Child = CType(XamlReader.Load(New XmlTextReader(New StringReader(ppCont.ToString))), UIElement)
reedited: this is how it looks like
I also faced a similar problem while using the MouseEnter and MouseLeave events. There is a strange behaviour of the MouseEnter event on WPF, don't know if it's a bug. When you enter the item in consideration from the top the flickering happens. Entering the item from any other direction gives you a smooth popup. So to avoid it, I removed the:
AllowsTransparency = True
part.
EDITED:
While still unable to find a perfect behaviour to my need, I figured out that this isn't actually a bug as described by Scott Hanselman here
However I wasn't able to compare the problem to mine and sort it out. Anyway, to have the animation features, I came up with a solution that would atleast reduce the extra opening or closure of the Popup control by checking the current position of the mouse. I defined a variable
Point currPoint = new Point();
And then in the MouseEnter event or handler:
ListViewItem listViewItem = e.Source as ListViewItem;
if(currPoint!=e.GetPosition(listViewItem))
compToStrategyVM.OpenPopup(listViewItem, listViewPopup);
Similarly in the MouseLeave event or handler:
ListViewItem listViewItem = e.Source as ListViewItem;
if (currPoint != e.GetPosition(listViewItem))
compToStrategyVM.ClosePopup(listViewPopup);
Here compToStrategyVM refers to my ViewMode and listViewPopup refers to the name of the Popup control. Though the issue still persists, but by this approach the flickering effect has been reduced to a considerable fraction.
After reading the comments I believe you are using the incorrect event; a MouseMove event will be continually trigged and with each time the popup to show/hide or flicker.
You want to use the MouseEnter and MouseLeave events.

How to add scrolling buttons to a data bound, horiztonal list

So I have a List, which contains items. Right now they are thumbnails of pictures. I wanted this list to be bound to a changing list in code behind, so I used a Listbox. However, I needed this box to flow horizontally. So it is styled as a StackPanel. Lastly, I want buttons to control the scrolling, not scrollbars. That's the part that does not work Here's a code sample :
<UserControl x:Class="TestBench.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<Style x:Key="StackHorz" TargetType="ListBox">
<Style.Setters>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" Background="AliceBlue" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer BorderBrush="DarkGreen" BorderThickness="2" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Button x:Name="_Next" Content="NEXT" Height="20" Width="40" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
<Button x:Name="_Prev" Content="PREV" Height="20" Width="40" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
<ListBox x:Name="TestList" Height="100" Width="800" VerticalAlignment="Top">
...Insert ListItems...
</ListBox>
</Grid>
In this example the listbox is not bound, but I do need to be able to set ItemsSource={Binding Content}. Code behind I tried was :
namespace TestBench
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
TestList.Style = this.Resources["StackHorzTop"] as Style;
_Next.Click += new RoutedEventHandler(_Next_Click);
_Prev.Click += new RoutedEventHandler(_Prev_Click);
}
void _Prev_Click(object sender, RoutedEventArgs e)
{
TestList.ScrollIntoView(TestList.Items[0]);
}
void _Next_Click(object sender, RoutedEventArgs e)
{
TestList.ScrollIntoView(TestList.Items[TestList.Items.Count - 1]);
}
}
}
But the ScrollIntoView does nothing. I also tried getting the ScrollViewer as a VisualTreeHelper.GetChild() of the list box, but scrolling there using ScrollToHorizontalOffset() does nothing either.
I know it's a weird way to set things up, but I need all 3 functionalities (Binding, Horizontal orientation, No scroll bars with button scrolling). Anyone know where I am going wrong on this one?
Thanks in advance,
Chart.
Maybe you can try putting your listbox in a ScrollViewer and style the ScrollViewer so that the scroll bars are not visible (only the buttons).
More info on the ScrollViewer's templatable parts can be found here.

Resources