gpt4 book ai didi

c# - 防止取消选择列表框中最后一个选定项目的最佳方法

转载 作者:太空宇宙 更新时间:2023-11-03 13:40:22 24 4
gpt4 key购买 nike

我需要在 wpf 中为 ListBox 控件实现自定义行为。这个想法是禁用取消选择最后选择的元素。根据默认行为,当用户用鼠标单击所选项目时,按住 ctrl 键,选择消失。我需要实现一些逻辑,使列表框在用户在最后一个选定项目上单击鼠标+ctrl 时不执行任何操作。

我发现的唯一方法是订阅 ListBox.SelectionChanged 并执行如下操作:

private static void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = sender as ListBox;
if (listBox != null && e.RemovedItems != null && e.RemovedItems.Count == 1)
{
var removed = e.RemovedItems[0];
if (listBox.SelectedItems.Count == 0)
{
if (listBox.SelectionMode == System.Windows.Controls.SelectionMode.Single)
{
listBox.SelectedItem = removed;
}
else
{
listBox.SelectedItems.Add(removed);
}

e.Handled = true;
}
}
}

但是这个解决方案不适合我,因为在这种情况下,当 ListBox.SelectedItem 绑定(bind)到 viewmodel 属性时会发生一些不需要的调用。

伪调用堆栈(当取消选择所选项时):

  1. SelectedItem 更改为 null

  2. listBox_SelectionChanged 被调用

  3. SelectedItem 设置为之前的值

我只希望第 1 步和第 3 步永远不会发生。这很重要,因为当 SelectedItem 更改时,会启动一些长时间运行的异步操作。

谢谢,如有任何建议,我们将不胜感激!

最佳答案

找到解决方案。在 ListBox 上处理 PreviewMouseLeftButtonDown 对我来说效果很好。作为附加属性(property)制作。

顺便说一句:我能以某种方式关闭这个问题吗?

public static class ListBoxAttachedProperties
{
public static readonly DependencyProperty DisableUnselectLast =
DependencyProperty.RegisterAttached(
"DisableUnselectLast", typeof(bool), typeof(ListBox),
new PropertyMetadata(false, DisableUnselectLastChangedCallback));

public static bool GetDisableUnselectLast(DependencyObject d)
{
return (bool)d.GetValue(DisableUnselectLast);
}

public static void SetDisableUnselectLast(DependencyObject d, bool value)
{
d.SetValue(DisableUnselectLast, value);
}

private static void DisableUnselectLastChangedCallback(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is ListBox))
{
return;
}

var selector = d as ListBox;
bool oldValue = (bool)e.OldValue;
bool newValue = (bool)e.NewValue;

if (oldValue == newValue)
{
return;
}

if (oldValue == false)
{
selector.PreviewMouseLeftButtonDown += listBox_PreviewMouseLeftButtonDown;
}
else
{
selector.PreviewMouseLeftButtonDown -= listBox_PreviewMouseLeftButtonDown;
}
}

private static void listBox_PreviewMouseLeftButtonDown(
object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var listBox = sender as ListBox;
if (listBox != null && listBox.SelectedItems.Count == 1)
{
UIElement container = listBox.ItemContainerGenerator
.ContainerFromItem(listBox.SelectedItems[0]) as UIElement;

if (container != null)
{
var pos = e.GetPosition(container);
var result = VisualTreeHelper.HitTest(container, pos);
if (result != null)
{
e.Handled = true;
}
}
}
}
}

关于c# - 防止取消选择列表框中最后一个选定项目的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17276214/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com