簡體   English   中英

如何獲取選定的列表框項以更新另一個列表框?

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

我是wpf和mvvm的新手,我希望這是有道理的...

我有一個CheckBox項目的ListBox。 當我選中或取消選中某個項目時,我想知道如何觸發事件或使我能夠將所選項目文本添加到其他ListBox的功能。

到目前為止,這是我所做的:

XAML:

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

主要ViewModel類:

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

此類檢查由小型類正確處理,但是我無法弄清楚該類如何在管理其他ListBox的Main ViewModel類中調用方法,或者我應該怎么做。

謝謝您的幫助!

根據菲利波·維加尼(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>

我建議將其他ListBox的ItemsSource綁定到相同的ObservableCollection,然后使用Converter來獲取所選項目。 這樣一來,您就不必再搞亂附加和分離事件處理程序了。 轉換器將是:

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

您需要將轉換器放在應用程序或窗口的“資源”部分中,以便可以在ListBox中使用它:

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

然后,您對其他ListBox的ItemsSource的綁定將如下所示:

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

我建議使用ICommand並使用AttachedCommandBehaviour將其綁定到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中,您將擁有一個處理check / uncheck事件的命令。 您可以將Prism用於實現ICommand的類(稱為DelegateCommand),可以從nuget中獲取它:

Install-Package Prism.Core

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