【问题标题】:How to check Checkboxes in XAML?如何检查 XAML 中的复选框?
【发布时间】:2019-05-29 02:50:06
【问题描述】:

我有一个对象列表作为ObservableCollection<MyObject>。我已经能够在 DataGrid 中使用 XAML 在组合框中显示这些对象的 name 属性。

现在我有另一个对象AnotherObject,它有一个定义为字符串列表的属性,并且该列表中的每一项都是上面提到的 MyObject 的 name 属性。

在组合框中,我想显示MyObject.name 属性,前面有一个复选框。 假设复选框中有 30 个项目,AnotherObject.names 的一个实例包含其中三个。 现在我想选中那些等于AnotherObject.names中的三个项目的复选框。

我怎样才能做到这一点?

一些代码:

MyObjectViewModel.cs:

public class MyObjectViewModel
{
    private MyObject _myObject;

    public MyObjectViewModel(MyObject myObject)
    {
        this._myObject = myObject;
    }

    public MyObject MyObject
    {
        get
        {
            return _myObject;
        }
        set
        {
            _myObject = value;
        }
    }

    public string Name
    {
        get { return _myObject.Name;  }
        set
        {
            _myObject.Name = value;
        }
    }

    public override string ToString()
    {
        return Name;
    }
}

另一个ObjectRowViewmodel.cs:

public class AnotherObjectRowViewModel : INotifyPropertyChanged
{
    private AnotherObject _anotherObject;
    private ObservableCollection<MyObjectViewModel> _myObjects;

    public AnotherObjectRowViewModel(AnotherObject anotherObject, ObservableCollection<MyObjectViewModel> myObjects)
    {
        this._anotherObject = anotherObject;
        this._myObjects = myObjects;
    }

    public AnotherObject AnotherObject
    {
        get
        {
            return _anotherObject;
        }
        set
        {
            this._anotherObject = value;
        }
    }

    public string Name
    {
        get { return _anotherObject.Name; }
        set { _anotherObject.Name = value; }
    }

    public ObservableCollection<MyObjectViewModel> MyObjects {
        get
        {
            return this._myObjects;
        }
        set
        {
            _myObjects = value;
        }
    }

    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    {
        add
        {
            //throw new NotImplementedException();
        }

        remove
        {
            //throw new NotImplementedException();
        }
    }
}

这就是我在 XAML 文件中尝试的:

<DataGridTemplateColumn x:Name="NamesColumn" Header="Names">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox Name="Name" DataContext="{Binding}" ItemsSource="{Binding Path=myObjects}" IsEditable="True" IsReadOnly="True" 
                          VerticalAlignment="Center" SelectionChanged="OnDetailParamsSelectionChanged" >
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <CheckBox x:Name="chbNames" Width="20" VerticalAlignment="Center" Checked="OnChbDetailParamsCheckBoxChecked" Unchecked="OnChbDetailParamsCheckBoxChecked"></CheckBox>
                                <TextBlock DataContext="{Binding Path=MyObject}" Text="{Binding Path=Name, Converter={StaticResource StringListConverter}}" VerticalAlignment="Center" />
                            </StackPanel>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                </ComboBox>
            </Grid>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

一个例子: 组合框包含 30 个名称的列表(Name1,...,Name30);

AnotherObject.names 是 { Name1, Name2, Name4, Name7 };

在组合框中,选定的项目应为 Name1、Name2、Name4、Name7。所有其他项目应保持未选中状态。

2019-01-06 更新: 这意味着 Combobox 的 ItemsSource={Binding} 是 MyObject 但选中的项目应存储在 AnotherObject 中。这就是为什么每当我勾选复选框时都会出现此异常的原因:

System.Windows.Data Error: 40 : BindingExpression path error: 'xxx' property not found on 'object' ''MyObjectViewModel' (HashCode=34649765)'. BindingExpression:Path=xxx.DetailParams; DataItem='MyObjectViewModel' (HashCode=34649765); target element is 'CheckBox' (Name='chbDetailParams'); target property is 'IsChecked' (type 'Nullable`1')

根据IsItemsSelectedConverter,我的 XAML 包含以下代码 sn-p:

<UserControl.Resources>
    <ctb:IsItemSelectedConverter x:Key="IsItemSelectedConverter"/>
</UserControl.Resources>

checkboxes 的 IsChecked 属性如下所示:

IsChecked="{Binding Path=Names, Mode=TwoWay, Converter={StaticResource IsItemSelectedConverter}}"

但它不起作用。调试此代码时,从未使用过 IsItemsSelectedConverter。

【问题讨论】:

  • 你能发布概述这些结构的代码吗?我想我明白你在寻找什么,但我不是 100% 确定。
  • 我在您的代码中看不到Names。我相信您可以在提出问题之前更多简化您的问题。

标签: c# wpf xaml checkbox


【解决方案1】:

MyObject 的视图模型中创建一个布尔属性,即在MyObjectViewModel 中,如果NameAnotherObject 的名称列表中,它将返回一个值。

【讨论】:

  • 好吧,我认为如果 anotherObject.names 只是一个字符串而不是字符串列表,这可能会起作用。请注意已编辑的问题。
【解决方案2】:

创建一个 IsItemSelectedConverter 并传入数据模型中的对象列表。在一个新类中实现IValueConverter 并将每个复选框的 IsChecked 属性绑定到两件事:值应该是当前项目,参数应该是项目列表。转换器应确定当前项目是否在项目列表中并返回适当的布尔值。

您必须创建一个转换器实例供 UI 使用。我通常在一个单独的资源字典中定义转换器,使所有 XAML 文件全局可用。

我的 IsItemSelectedConverter 看起来像这样:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {

            if (value is MyObjectViewModel objectViewModel && parameter is AnotherObjectRowViewModel anotherObjectRowViewModel)
            {
                return anotherObjectRowViewModel.MyObjects.Contains(objectViewModel);
            }
            return false;
        }

在 XAML 上,我的 CheckBox 代码如下所示:&lt;CheckBox IsChecked="{Binding Mode=OneWay, Converter={StaticResource converter}, ConverterParameter={StaticResource viewModel} }" /&gt;

请注意:代码存在一些问题会阻止它按原样运行,但我假设这些是复制和粘贴实际代码的产物。

【讨论】:

  • 我想我明白了你的建议,但我该怎么做呢?如何将 Checkbox 的 IsChecked 属性绑定到 AnotherObject 和 MyObject 中的 Names 列表?一些代码?? :-) 当我尝试将 {Binding...} 与 ConverterParameter 结合使用时,会导致:XamlParseException:无法为 Binding ConverterParameter 属性设置绑定。只能为 DependencyObject 的 DependencyProperty 设置绑定。
  • 确保您的 Window.Resources(或另一个链接的资源字典)包含一个名为“converter”的 IsItemsSelectedConverter。 CheckBox 上的 IsChecked 表达式将如下所示:IsChecked="{Binding Mode=OneWay, Converter={StaticResource converter}, ConverterParameter={StaticResource viewModel} }"。我不确定您是如何存储视图模型的,因此您必须进行相应调整。
猜你喜欢
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2017-01-04
  • 2015-12-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多