传递通用的ObservableCollection作为CommandParameter

时间:2019-01-20 17:44:09

标签: c# wpf mvvm

我为对象使用了许多不同的ViewModels,它们显示在复选框列表中。 所有子类(长颈鹿和大象)都继承于主要的哺乳动物。 对于复选框的每个列表,都有一个用于取消选择复选框的按钮。 我想使用适用于所有子类的通用方法。 我考虑过通过单击按钮将使用的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}" />

MainViewModel

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

                });
            }
        }

ViewModels

 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 个答案:

答案 0 :(得分:1)

处理此问题的正确方法是将ObservableCollection<T>强制转换为IList,然后将IList的每个元素强制转换为基类。

public ICommand ClearSelection
{
    get
    {
        return _clearSelection ?? new RelayCommand((x) =>
        {
            IList coll = (IList) x;

            foreach (var obj in coll)
            {
                ((MammalViewModel)obj).Checked = false;
            }
        });
    }
}

或者您也可以将ObservableCollection<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;
            }
        });
    }
}

答案 1 :(得分:0)

找到了解决方案:

x0 = sin(t);
x1 = cos(t);
scalar_matrix = x0.^2 + x0;
matrix = [x0; x1; 2*x0; x1.^2];