Reputation: 917
I am creating UWP app, and I maked external arrow "marker" of selected item in listview...
I have managed to achieve this with next code:
var current = lvMain.Items.FirstOrDefault(a => (a as MyModel).Selected) as MyModel;
ListViewItem selected = lvMain.ContainerFromItem(current) as ListViewItem;
GeneralTransform generalTransform1 = gvEpg.TransformToVisual(selected);
Point currentPoint = generalTransform1.TransformPoint(new Point());
In Scroll change event I am calling this and set the arrow position by the Point of my item. And this is working.
But, I want to simplified this. Is there any kind of binding or something like that, that would make arrow always follow the item?
Upvotes: 2
Views: 996
Reputation: 1488
Here's the sample.
XAML MainPage
:
<Page.Resources>
<DataTemplate x:Key="DataTemplate">
<Canvas Height="80" Width="200">
<TextBlock Text="{Binding}"/>
</Canvas>
</DataTemplate>
</Page.Resources>
<StackPanel Orientation="Horizontal">
<ListView x:Name="ListView" Width="400"
SelectionChanged="ListView_OnSelectionChanged"
ItemTemplate="{StaticResource DataTemplate}"/>
<Canvas x:Name="ParentCanvas">
<Image x:Name="Arrow"
Stretch="UniformToFill" Width="200" Height="80"
Source="Assets/Red_Left_Arrow.png"/>
</Canvas>
</StackPanel>
Code behind:
private readonly List<string> _names = new List<string>();
private Visual _rectangleVisual;
private Visual _parentVisual;
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 32; i++)
{
_names.Add("item " + i);
}
ListView.ItemsSource = _names;
_parentVisual = ElementCompositionPreview.GetElementVisual(ParentCanvas);
_rectangleVisual = ElementCompositionPreview.GetElementVisual(Arrow);
var border = VisualTreeHelper.GetChild(ListView, 0) as Border;
var scrollViewer = border.Child as ScrollViewer;
var scrollerProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);
var offsetExpressionAnimation = _rectangleVisual.Compositor.CreateExpressionAnimation("Scroller.Translation.Y");
offsetExpressionAnimation.SetReferenceParameter("Scroller", scrollerProperties);
_rectangleVisual.StartAnimation("Offset.Y", offsetExpressionAnimation);
}
private void ListView_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listViewItem = ListView.ContainerFromItem(ListView.SelectedItem) as ListViewItem;
var listItemVisual = ElementCompositionPreview.GetElementVisual(listViewItem);
_parentVisual.Offset = new Vector3(_parentVisual.Offset.X, listItemVisual.Offset.Y, 0);
}
Looks like what you asked for:
Upvotes: 3