代码之家  ›  专栏  ›  技术社区  ›  br0ken.pipe

将泛型ObservableCollection作为commandParameter传递

  •  0
  • br0ken.pipe  · 技术社区  · 5 年前

    我为对象使用了许多不同的视图模型,它们显示在复选框列表中。 所有的亚纲(长颈鹿和大象)都继承自主要的哺乳动物。 对于每个复选框列表,都有一个按钮来取消选择它们。 我想使用一个能处理所有子类的通用方法。 我想通过点击按钮将使用过的ObservableCollection传递给命令, 不幸的是,我不能动态地识别它是哪个子类并正确地进行转换。

    XAML

    <ListBox SelectionMode="Multiple" ItemsSource="{Binding Path=Giraffes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Path=Text}" IsChecked="{Binding Path=Checked}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
    <Button Content="Clear" Command="{Binding ClearSelection}" CommandParameter="{Binding Path=Giraffes}" />
    

    主视图模型

    private ICommand _clearSelection;
    public ICommand ClearSelection
            {
                get
                {
                    return _clearSelection ?? new RelayCommand((x) =>
                    {
    
                        ObservableCollection<Giraffe> observableCollection = (ObservableCollection<Giraffe>) x;
    
                        foreach (var giraffe in giraffes)
                        {
                            giraffe.Checked = false;
                        }
    
                    });
                }
            }
    

    视图模型

     public class MammalViewModel : BaseViewModel 
        {
            private bool _checked;
    
            public bool Checked
            {
                get => _checked;
                set
                {
                    if (value == _checked) return;
                    _checked = value;
                    OnPropertyChanged("Checked");
                }
            }
    
    
            private string _text;
            public string Text
            {
                get => _text;
                set
                {
                    if (value == _text) return;
                    _text = value;
                    OnPropertyChanged("Text");
                }
            }
        }
    
         public class GiraffeViewModel : MammalViewModel { }
         public class ElephantViewModel : MammalViewModel { }
    
    2 回复  |  直到 5 年前
        1
  •  1
  •   Alex.Wei    5 年前

    正确的处理方法是 ObservableCollection<T> IList ,然后将 伊利斯特 到基类。

    public ICommand ClearSelection
    {
        get
        {
            return _clearSelection ?? new RelayCommand((x) =>
            {
                IList coll = (IList) x;
    
                foreach (var obj in coll)
                {
                    ((MammalViewModel)obj).Checked = false;
                }
            });
        }
    }
    

    或者你也可以铸造 观察收集<t> IEnumerable 然后使用 Cast<TResult> 将整个集合强制转换为的扩展方法 ObservableCollection<baseclass> .

    public ICommand ClearSelection
    {
        get
        {
            return _clearSelection ?? new RelayCommand((x) =>
            {
                ObservableCollection<MammalViewModel> coll = ((IEnumerable)x).Cast<ObservableCollection<MammalViewModel>();
    
                foreach (var obj in coll)
                {
                    obj.Checked = false;
                }
            });
        }
    }
    
        2
  •  0
  •   br0ken.pipe    5 年前

    找到一个解决方案:

     public ICommand ClearSelection
            {
                get
                {
                    return _clearSelection ?? new RelayCommand((x) =>
                    {
                        switch (x)
                        {
                            case ObservableCollection<GiraffeViewModel> giraffes:
                                DeCheckElements(giraffes);
                                break;
                            case ObservableCollection<ElephantViewModel> elephants:
                                DeCheckElements(elephants);
                                break;
                        }
                    });
                }
            }