如何获取选定的列表框项以更新另一个列表框
本文关键字:列表 另一个 更新 何获取 获取 | 更新日期: 2023-09-27 18:30:32
我对 wpf 和 mvvm 很陌生,我希望这是有意义的......
我有一个复选框项的列表框。 当我选中或取消选中某个项目时,我想知道如何触发事件或任何使我能够将所选项目文本添加到不同 ListBox 的内容。
以下是我到目前为止所做的:
XAML:
<ListBox ItemsSource="{Binding Target}" IsEnabled="{Binding IsControlEnabled}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding TitleName}" IsChecked="{Binding IsChecked}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
主视图模型类:
private ObservableCollection<CheckServerItem> _target = new ObservableCollection<CheckServerItem>();
用于处理复选框事件的小型类:
public class CheckServerItem : ViewModelBase
{
private bool _isChecked { get; set; }
private string _Title { get; set; }
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
RaisePropertyChanged("IsChecked");
}
}
public string TitleName
{
get { return _Title; }
set
{
_Title = value;
RaisePropertyChanged("TitleName");
}
}
}
检查由小类正确处理,但我无法弄清楚如何让该类调用主 ViewModel 类中管理其他 ListBox 的方法或我应该调用的方法。
感谢您的帮助!
根据菲利波·维加尼的回答,如果您仅通过鼠标选中/取消选中复选框,您还可以执行以下操作,
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding TitleName}"
IsChecked="{Binding IsChecked}"
Command="{Binding DataContext.SelectionChangedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
CommandParameter="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
我建议将其他 ListBox 的 ItemsSource 绑定到同一个 ObservableCollection,然后使用转换器来获取选定的项目。 这样,您就不必为附加和分离事件处理程序而烦恼。 转换器将是:
[ValueConversion(typeof(object), typeof(object))]
public class IsCheckedConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ObservableCollection<CheckServerItem> result = new ObservableCollection<CheckServerItem>();
foreach(CheckServerItem item in (value as ObservableCollection<CheckServerItem>))
{
if (item.IsChecked)
{
result.Add(item);
}
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Binding.DoNothing;
}
}
您需要将转换器放在应用或窗口的"资源"部分中,以便可以在列表框中使用它:
<this:IsCheckedConverter x:Key="MyIsCheckedConverter" />
然后,其他列表框的 ItemsSource 的绑定将如下所示:
<ListBox ItemsSource="{Binding Target, Converter={StaticResource MyIsCheckedConverter}}>
我建议使用ICommand并使用AttachedCommandBehavior将其绑定到CheckBox的Checked RoutedEvent(您可以在nuget上获取它):
Install-Package AttachedCommandBehavior
XAML 如下所示:
...
xmlns:acb="clr-namespace:AttachedCommandBehavior;assembly=AttachedCommandBehavior"
...
<ListBox ItemsSource="{Binding Target}"
IsEnabled="{Binding IsControlEnabled}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding TitleName}"
IsChecked="{Binding IsChecked}">
<acb:CommandBehaviorCollection.Behaviors>
<acb:BehaviorBinding Event="Checked"
Command="{Binding DataContext.SelectionChangedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
CommandParameter="{Binding}" />
<acb:BehaviorBinding Event="Unchecked"
Command="{Binding DataContext.SelectionChangedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
CommandParameter="{Binding}" />
</acb:CommandBehaviorCollection.Behaviors>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
然后在 ViewModel 中,您将有一个处理检查/取消选中事件的命令。您可以将 Prism 用于实现 ICommand 的类,该类称为 DelegateCommand,您可以从 nuget 获取它:
Install-Package Prism.Core
视图模型中的命令可能如下所示:
private DelegateCommand<CheckServerItem> selectionChangedCommand;
public DelegateCommand<CheckServerItem> SelectionChangedCommand
{
get
{
return this.selectionChangedCommand ?? (this.selectionChangedCommand = new DelegateCommand<CheckServerItem>((x) =>
{
if (x.IsChecked)
{
MyOtherList.Add(x);
} else
{
MyOtherList.Remove(x);
}
}));
}
}