WPF 点击ListViewItem中的Button,如何获取选中的是第几行?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF 点击ListViewItem中的Button,如何获取选中的是第几行?相关的知识,希望对你有一定的参考价值。

查到的资料是这个:
里面的按钮绑定了Button_Click之后
void Button_Click(object sender, RoutedEventArgs e)

ListViewItem local = ((sender as Button).Tag as ListViewItem);

or
listView1.SelectedItem = ((Button) sender).DataContext;
但是之后呢?求教

你这还是标准的winform的思考方式。建议如下方法
后台设置属性observablecollection<type> items,这个type根据你自己的需求来定,type里面需要定义isselected属性。xaml里面itemssource绑定到items,并设置item template,呈现出button,还要定义itemcontainerstyle,把item的isselected绑定到type.isselected。这样你前台选中哪个,后台哪个的isselected就是true。
参考技术A 最简单的做法就是listviewitem绑定的数据实体有一个计数字段对应行号。那么点击Item的时候直接读取这个计数属性就可以了。希望提的意见能给予你帮助,谢谢。 参考技术B 应该会有selectedItemIndex之类的语句

滚动ListViewItem位于ListView的顶部

在WPF中,我知道我可以使用ListView.ScrollIntoView将特定项目滚动到视图中,但它总是会进行最少量的滚动以便显示项目。

如何使其滚动以便我想要显示的项目滚动到ListView的顶部?

我曾经考虑过两次调用ScrollIntoView,一次是针对我想要的项目,一次针对最后显示的项目,但我不知道如何找出最后显示的项目。

答案

我们可以通过获取ListView的ControlTemplate中存在的ScrollViewer来实现。如果您可以访问ScrollViewer,则会显示不同滚动方法的a lot

首先,我们可以创建一个我们想要将此效果添加到的ListView:

<ListView ItemsSource="{Binding Percents}"
      SelectionChanged="OnSelectionChanged"
      x:Name="uiListView"/>

public List<int> Percents { get; set; }

public Window1()
{
    InitializeComponent();

    Percents = new List<int>();
    for (int i = 1; i <= 100; i++)
    {
        Percents.Add(i);
    }
    this.DataContext = this;
}

我们还需要一些可以从ListView获取ScrollViewer的东西。我以前使用类似于此的东西来处理自定义滚动,我们也可以在这里使用它。

public static DependencyObject GetScrollViewer(DependencyObject o)
{
    if (o is ScrollViewer)
    { return o; }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
    {
        var child = VisualTreeHelper.GetChild(o, i);

        var result = GetScrollViewer(child);
        if (result == null)
        {
            continue;
        }
        else
        {
            return result;
        }
    }

    return null;
}

现在,我们只需要处理SelectionChanged事件。因为我们正在尝试将项目滚动到列表的顶部,所以最好的选项是滚动到底部,然后重新向上滚动到我们选择的项目。正如您所说,ScrollIntoView将滚动直到项目可见,因此一旦所选项目向上滚动回到顶部,它将停止我们所选项目在列表的最顶部。

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ScrollViewer scrollViewer = GetScrollViewer(uiListView) as ScrollViewer;
    scrollViewer.ScrollToBottom();

    uiListView.ScrollIntoView(e.AddedItems[0]);
}
另一答案

这是@rmoore的答案的替代方案,可以避免滚动到底部。另请注意,这仅适用于SelectionMode=Single的情况。

如果ScrollViewer.CanContentScroll=True ScrollViewer可以直接滚动到SelectedIndex

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ScrollViewer scrollViewer = GetScrollViewer(uiListView) as ScrollViewer;      
    scrollViewer.ScrollToVerticalOffset(listView.SelectedIndex);
}

如果ScrollViewer.CanContentScroll=False需要一些额外的XAML:

<ListView ScrollViewer.CanContentScroll="False" ItemsSource="{Binding Percents}" x:Name="uiListView">
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <EventSetter Event="Selected" Handler="OnSelected"/>
        </Style>
     </ListView.ItemContainerStyle>
</ListView>

并且ScrollViewer可以移动到ListViewItem顶部的垂直偏移。

private void OnSelected(object sender, RoutedEventArgs e)
{
    ScrollViewer scrollViewer = GetScrollViewer(uiListView) as ScrollViewer;      

    ListViewItem listViewItem = (ListViewItem)e.Source;
    Point offset = listViewItem.TranslatePoint(new Point(), scrollViewer);
    scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset.Y);
}

以上是关于WPF 点击ListViewItem中的Button,如何获取选中的是第几行?的主要内容,如果未能解决你的问题,请参考以下文章

WPF动态添加带有detals的ListViewItem

WPF:防止在 Shift + 箭头上选择 ListViewItem

求助WPF ListViewItem样式问题

WPF:改变ListBoxItem和ListViewItem的颜色

WPF ListViewItem IsSelected 仅在视图中滚动后影响

C# Wpf 如何使用其中的按钮更改 Listviewitem 的高度?