我使用一个WPF ListView来显示和选择/取消选择一些项,但是有一些条件用户不能选择/取消选择一个项,我应该在后面的代码中处理它。我尝试使用ListView.SelectionChanged
事件来处理它,但问题是,当我在后面的代码中更改所选项时(如果它被取消选中或以另一种方式再次选择它),事件会再次触发,我不想这样做。
对选择/取消选择ListView项设置条件的最佳方法是什么?
我试图用ListView.PreviewMouseLeftButtonDown
事件而不是ListView.SelectionChanged
来解决这个问题。但我想知道是否有更好的方法?
发布于 2022-12-01 04:50:52
可能还有其他WPF控件(特别是第三方控件)可以更优雅地处理这一问题。此外,您还可以连接到ListView的样式,以更改鼠标越位行为。
不过,作为一种简单的方法,通过使用SelectionChanged
事件有效地“撤消”我们认为无效的任何选择,我能够完成您正在寻找的任务。
首先,xaml中的一个简单的ListView:
<ListView
x:Name="ItemsLv"
SelectionChanged="ItemsLv_SelectionChanged"
SelectionMode="Single" />
在这里,SelectionMode
是Single
是很重要的,因为当多个项目被选中时,取消选择的方法要复杂得多。
然后,一个用ToString()重载表示列表项的对象,这样我们就不必篡改数据模板和绑定了。
public class MyListViewItem
{
public string Text { get; set; }
public bool IsSelectable { get; set; }
public override string ToString()
{
return Text;
}
}
这个对象只是表示一个字符串(我们的数据),并配以一个布尔值,表示我们是否希望这个项目是可选的。
然后,用几个测试项填充列表的快速小设置:
public MainWindow()
{
InitializeComponent();
var items = new List<MyListViewItem>
{
new() { Text = "Item One", IsSelectable = true },
new() { Text = "Item Two", IsSelectable = true },
new() { Text = "Item Three", IsSelectable = false },
new() { Text = "Item Four", IsSelectable = true }
};
ItemsLv.ItemsSource = items;
}
最后是“魔法”。SelectionChanged事件处理程序:
private void ItemsLv_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// if this event wasn't caused by a new item that wasn't already
// selected being selected, don't do anything extra
if (e.AddedItems.Count <= 0)
{
return;
}
// get the newly selected item and cast it to a MyListViewItem so we can inspect the IsSelectable property
var selectedItem = (MyListViewItem)ItemsLv.SelectedItem;
// if it's a selectable item, we don't need to intervene
if (selectedItem.IsSelectable)
{
return;
}
// we made it this far that means we tried to select an item that should NOT be selectable
// if the new selected item caused us to UNselect an old item, put the selection back
if (e.RemovedItems.Count > 0)
{
ItemsLv.SelectedItem = e.RemovedItems[0];
}
// otherwise (the first selection ever?) just set selection back to null
else
{
ItemsLv.SelectedItem = null;
}
}
希望那里的代码注释能清楚地说明到底发生了什么。
https://stackoverflow.com/questions/74630177
复制相似问题