简体   繁体   English

如何获取选定的列表框项以更新另一个列表框?

[英]How to get selected listbox item to update another listbox?

I'm very new to wpf and mvvm and I hope this makes sense... 我是wpf和mvvm的新手,我希望这是有道理的...

I have a ListBox of CheckBox items. 我有一个CheckBox项目的ListBox。 When I check or uncheck an item, I want to know how to fire an event or whatever that will give me the ability to add the selected items text to different ListBox. 当我选中或取消选中某个项目时,我想知道如何触发事件或使我能够将所选项目文本添加到其他ListBox的功能。

Here's what I've done thus far: 到目前为止,这是我所做的:

XAML: XAML:

<ListBox ItemsSource="{Binding Target}" IsEnabled="{Binding IsControlEnabled}">
     <ListBox.ItemTemplate>
          <DataTemplate>
                <CheckBox Content="{Binding TitleName}" IsChecked="{Binding IsChecked}" />
          </DataTemplate>
     </ListBox.ItemTemplate>
</ListBox>

Main ViewModel Class: 主要ViewModel类:

private ObservableCollection<CheckServerItem> _target = new ObservableCollection<CheckServerItem>();

Small Class to handle checkbox events: 小类来处理复选框事件:

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");
        }
    }
}

The checks are handled correctly by the small class, but I can't figure out how to have that class either call a method in the Main ViewModel Class that manages the other ListBox or what I should. 此类检查由小型类正确处理,但是我无法弄清楚该类如何在管理其他ListBox的Main ViewModel类中调用方法,或者我应该怎么做。

Thanks for the help! 谢谢您的帮助!

Based on the answer of Filippo Vigani, you can also do the following if you only check/uncheck the checkbox by mouse, 根据菲利波·维加尼(Filippo Vigani)的回答,如果您仅通过鼠标选中/取消选中复选框,也可以执行以下操作:

        <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>

I would recommend binding the other ListBox's ItemsSource to the same ObservableCollection but then using a Converter to get you just the selected items. 我建议将其他ListBox的ItemsSource绑定到相同的ObservableCollection,然后使用Converter来获取所选项目。 Then you don't have to mess around with attaching and detaching event handlers at all. 这样一来,您就不必再搞乱附加和分离事件处理程序了。 The Converter would be: 转换器将是:

[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;
    }
}

You would need to put the converter in the Resources section of your App or Window so that you can use it in your ListBox: 您需要将转换器放在应用程序或窗口的“资源”部分中,以便可以在ListBox中使用它:

<this:IsCheckedConverter x:Key="MyIsCheckedConverter" />

And then your binding for the other ListBox's ItemsSource would look like this: 然后,您对其他ListBox的ItemsSource的绑定将如下所示:

<ListBox ItemsSource="{Binding Target, Converter={StaticResource MyIsCheckedConverter}}>

I would suggest using an ICommand and bind it to the Checked RoutedEvent of the CheckBox using AttachedCommandBehaviour (you can get it on nuget): 我建议使用ICommand并使用AttachedCommandBehaviour将其绑定到CheckBox的Checked RoutedEvent(可以在nuget上获取它):

Install-Package AttachedCommandBehavior

the xaml would look something like this: 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>

and then in your ViewModel you would have a command that handles the check/uncheck event. 然后在ViewModel中,您将拥有一个处理check / uncheck事件的命令。 You can use Prism for a class that implements ICommand which is called DelegateCommand, you can get it from nuget: 您可以将Prism用于实现ICommand的类(称为DelegateCommand),可以从nuget中获取它:

Install-Package Prism.Core

The command in your viewmodel could be something like: 您的viewmodel中的命令可能类似于:

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);
                }
            }));
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM