C# UWP Listview/GridView 选中项的标记

C# UWP Listview/GridView mark of selected item

我正在创建 UWP 应用程序,我在列表视图中为所选项目制作了外部箭头“标记”...

像这样:

我已经通过下一个代码实现了这一点:

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());

在 Scroll change 事件中,我调用它并通过我的项目的 Point 设置箭头位置。这是有效的。

但是,我想简化这个。是否有任何类型的绑定或类似的东西,可以使箭头始终跟随项目?

这是示例。

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>

后面的代码:

    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);
    }

看起来像你要求的: