Tôi có thể nghĩ ra một vài cách để thực hiện việc này.
Một cách là bạn có thể liên kết ListBox.SelectedIndex
trong 2 Hộp danh sách của mình để thay đổi thông báo các thuộc tính ViewModel.
Ví dụ trong View của bạn:
<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>
Và trong ViewModel của bạn:
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");
}
}
Một cách khác sẽ có một tài sản gắn liền như 'GroupName', nơi bạn có thể Selectors nhóm (ListBox
thừa hưởng từ Selector
) để đảm bảo chỉ một Selector
trong nhóm có một mục được chọn cùng một lúc.
Ví dụ:
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);
}
}
}
Và trong View của bạn:
<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>
Nếu bạn phải bấm vào một mục hai lần trước khi nó được đánh dấu, bạn có thể sử dụng một cách giải quyết nhanh chóng như thế này:
<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>
Bạn muốn lựa chọn được xóa trong một ListBox khi lựa chọn được thực hiện trong ListBox khác? Tôi thấy câu hỏi của bạn khó hiểu. – Simon
Tôi về cơ bản muốn biết làm thế nào tôi có thể ràng buộc một cái gì đó giống như một IsFocused/IsSelected Listbox bất động sản để một bool trong mô hình xem của tôi. – user1722960
Bạn có thể liên kết SelectedIndex của một ListBox với một thuộc tính trong mô hình khung nhìn của bạn. Vì vậy, ví dụ khi SelectedIndexA của ListBoxA được thiết lập, bạn có thể đặt SelectedIndexB của ListBoxB thành -1 để xóa (các) lựa chọn của ListBoxB và ngược lại. Đó có phải là ý định của bạn không? – Simon