我有一个对象列表,为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;
}
}
AnotherObjectRowViewmodel.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: 这意味着组合框的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')
我的XAML包含根据 IsItemsSelectedConverter 的以下代码段:
<UserControl.Resources>
<ctb:IsItemSelectedConverter x:Key="IsItemSelectedConverter"/>
</UserControl.Resources>
IsChecked复选框的属性如下:
IsChecked="{Binding Path=Names, Mode=TwoWay, Converter={StaticResource IsItemSelectedConverter}}"
但是它不起作用。调试该代码后,永远不会使用IsItemsSelectedConverter。
答案 0 :(得分:0)
在MyObject
的视图模型中创建一个布尔属性,即在MyObjectViewModel
中创建一个布尔属性,如果Name
在AnotherObject
的名称列表中,则会返回一个值。 / p>
答案 1 :(得分:0)
创建一个IsItemSelectedConverter并传入数据模型中的对象列表。在新类中实现IValueConverter,并将每个复选框的IsChecked属性绑定到两件事:value应该是当前项目,而parameter应该是项目列表。转换器应确定当前项目是否在项目列表中,并返回适当的布尔值。
您将必须创建要使用的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代码如下:<CheckBox IsChecked="{Binding Mode=OneWay, Converter={StaticResource converter}, ConverterParameter={StaticResource viewModel} }" />
请注意:代码中存在一些问题,将阻止它按原样运行,但是我假设这些是复制和粘贴实际代码的产物。