首页 > 解决方案 > 如何将绑定列表作为参数传递给 IValueConverter?

问题描述

我有一个 CheckBoxes ComboBox 的多项选择,如下所示:

<ComboBox  ItemsSource="{Binding Animals}">
    <ComboBox.Resources>
        <Style TargetType="ComboBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ComboBoxItem">
                        <CheckBox
                            IsChecked="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type ComboBoxItem}}, Converter={StaticResource checkboxConverter}}"
                            Command="{Binding Path=DataContext.AgregarRolCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
                            <CheckBox.CommandParameter>
                                <MultiBinding Converter="{StaticResource multiSelectionConverter}">
                                    <Binding Path="IsChecked" RelativeSource="{RelativeSource Self}"/>
                                    <Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType={x:Type ComboBoxItem}}"/>
                                </MultiBinding>
                            </CheckBox.CommandParameter>
                            <ContentPresenter />
                        </CheckBox>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ComboBox.Resources>
</ComboBox>

ComboBox 正在显示我在 ViewModel 中声明的动物列表,如下所示:

 public class ViewModel: ViewModelBase {
   public List < string > Animals {
    get {
     return new List < string > {
      "CAT",
      "GIRAFFE",
      "ELEPHANT",
      "DOG"
     };
    }
   }
   public List < string > SelectedAnimals {
    get {
     return new List < string > {
      "DOG",
      "CAT"
     };
    }
   }

我想要做的是,从一个名为 SelectedAnimals 的列表中,如果选择了动物以将 ComboBox 内的 CheckBox 显示为选中状态。为此,我为 CheckBox 的 IsChecked 属性创建了一个名为 CheckBoxCheckedConverter 的转换器,我想在其中向转换器发送该 ComboBoxItem 的当前动物和所选动物的列表,并比较当前动物是否在所选动物列表中。

我在 UserControl.Resources 中的 xaml 中声明转换器,如下所示:

 <UserControl.Resources>
        <converters:CheckBoxCheckedConverter x:Key="checkboxConverter" MyCollection="{Binding SelectedAnimals}"/>
        ...
</UserControl.Resources>

为了在我的转换器中接收 SelectedAnimals 列表,我在这篇文章之后完成了下一个代码

public class CheckBoxCheckedConverter : Freezable, IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (MyCollection.Contains(value.ToString()))
                return true;
            return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public CheckBoxCheckedConverter()
        {
            MyCollection = new ObservableCollection<string>();
        }

        protected override Freezable CreateInstanceCore()
        {
            return new CheckBoxCheckedConverter();
        }


        public static readonly DependencyProperty MyCollectionProperty =
        DependencyProperty.Register(nameof(MyCollection),
            typeof(ObservableCollection<string>), typeof(CheckBoxCheckedConverter),
            new FrameworkPropertyMetadata(null));

        public ObservableCollection<string> MyCollection
        {
            get { return GetValue(MyCollectionProperty) as ObservableCollection<string>; }
            set { SetValue(MyCollectionProperty, value); }
        }
    }

问题是 MyCollection 在转换器中以 null 的形式出现,并且由于尝试对 null 对象执行 .Contains() ,转换会引发错误。为什么转换器中的 MyCollection 变量为空?这种方法是正确的还是更好或更简单的方法?

标签: c#wpfmvvm

解决方案


问题是我传递了一个列表,而在转换器中我声明了一个 ObservableCollection。


推荐阅读