gpt4 book ai didi

c# - 一次只选择一个项目的多个 WPF 列表框

转载 作者:太空狗 更新时间:2023-10-29 20:00:03 28 4
gpt4 key购买 nike

我正在使用 MVVM 并在一个窗口上显示两个列表框。我同时从这两个列表框绑定(bind)到不同的字段,称为 A 和 B。然后 A 和 B 都在修改 C。为了完成这项工作,我只想一次从两个列表框 IsSelected 中选择一个项目,以便 A当 B IsSelected 时不覆盖 C。我该如何限制它?

最佳答案

我可以想到几种方法来做到这一点。

一种方法是您可以将 2 个 ListBox 的 ListBox.SelectedIndex 绑定(bind)到更改通知 ViewModel 属性。

例如在您的 View 中:

<ListBox SelectedIndex="{Binding SelectedIndexA}">
<ListBoxItem Content="Item 1"/>
<ListBoxItem Content="Item 2"/>
</ListBox>
<ListBox SelectedIndex="{Binding SelectedIndexB}">
<ListBoxItem Content="Item 1"/>
<ListBoxItem Content="Item 2"/>
</ListBox>

在你的 ViewModel 中:

public int SelectedIndexA
{
get { return _selectedIndexA; }
set
{
_selectedIndexA = value;
_selectedIndexB = -1;
OnPropertyChanged("SelectedIndexB");
}
}

public int SelectedIndexB
{
get { return _selectedIndexB; }
set
{
_selectedIndexB = value;
_selectedIndexA = -1;
OnPropertyChanged("SelectedIndexA");
}
}

另一种方法是使用附加属性,如“GroupName”,您可以在其中对选择器进行分组(ListBox 继承自 Selector)以确保只有一个 Selector 组中的任何一个时间都有一个选定的项目。

例如:

public static class SingleSelectionGroup
{
public static readonly DependencyProperty GroupNameProperty =
DependencyProperty.RegisterAttached("GroupName", typeof(string), typeof(SingleSelectionGroup),
new UIPropertyMetadata(OnGroupNameChanged));

public static string GetGroupname(Selector selector)
{
return (string) selector.GetValue(GroupNameProperty);
}

public static void SetGroupName(Selector selector, string value)
{
selector.SetValue(GroupNameProperty, value);
}

private static void OnGroupNameChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var selector = (Selector) dependencyObject;

if (e.OldValue != null)
selector.SelectionChanged -= SelectorOnSelectionChanged;
if (e.NewValue != null)
selector.SelectionChanged += SelectorOnSelectionChanged;
}

private static void SelectorOnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0)
return;

var selector = (Selector) sender;
var groupName = (string) selector.GetValue(GroupNameProperty);
var groupSelectors = GetGroupSelectors(selector, groupName);

foreach (var groupSelector in groupSelectors.Where(gs => !gs.Equals(sender)))
{
groupSelector.SelectedIndex = -1;
}
}

private static IEnumerable<Selector> GetGroupSelectors(DependencyObject selector, string groupName)
{
var selectors = new Collection<Selector>();
var parent = GetParent(selector);
GetGroupSelectors(parent, selectors, groupName);
return selectors;
}

private static DependencyObject GetParent(DependencyObject depObj)
{
var parent = VisualTreeHelper.GetParent(depObj);
return parent == null ? depObj : GetParent(parent);
}

private static void GetGroupSelectors(DependencyObject parent, Collection<Selector> selectors, string groupName)
{
var childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
var selector = child as Selector;
if (selector != null && (string) selector.GetValue(GroupNameProperty) == groupName)
selectors.Add(selector);

GetGroupSelectors(child, selectors, groupName);
}
}
}

在您的 View 中:

<ListBox my:SingleSelectionGroup.GroupName="Group A">
<ListBoxItem Content="Item 1 (Group A)"/>
<ListBoxItem Content="Item 2 (Group A)"/>
</ListBox>
<ListBox my:SingleSelectionGroup.GroupName="Group A">
<ListBoxItem Content="Item 1 (Group A)"/>
<ListBoxItem Content="Item 2 (Group A)"/>
</ListBox>

<ListBox my:SingleSelectionGroup.GroupName="Group B">
<ListBoxItem Content="Item 1 (Group B)"/>
<ListBoxItem Content="Item 2 (Group B)"/>
</ListBox>
<ListBox my:SingleSelectionGroup.GroupName="Group B">
<ListBoxItem Content="Item 1 (Group B)"/>
<ListBoxItem Content="Item 2 (Group B)"/>
</ListBox>

如果您必须在某个项目突出显示之前单击它两次,您可以使用如下快速解决方法:

<Style TargetType="ListBoxItem">
<Style.Triggers>
<EventTrigger RoutedEvent="GotKeyboardFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(ListBoxItem.IsSelected)">
<DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>

关于c# - 一次只选择一个项目的多个 WPF 列表框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12759507/

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