将WPF DataGridComboBoxColumn与MVVM一起使用-绑定到ViewModel中的属性 [英] Using WPF DataGridComboBoxColumn with MVVM - Binding to Property in ViewModel
问题描述
我正在使用出色的MVVM Light Toolkit.我的ViewModel公开了:
I'm using the excellent MVVM Light Toolkit. My ViewModel exposes:
public const string CourtCodesTypeCourtPropertyName = "CourtCodesTypeCourt";
private List<CourtType> _courtCodesTypes = new List<CourtType>();
public List<CourtType> CourtCodesTypeCourt
{
get
{
return _courtCodesTypes;
}
set
{
if (_courtCodesTypes == value)
{
return;
}
var oldValue = _courtCodesTypes;
_courtCodesTypes = value;
// Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
RaisePropertyChanged(CourtCodesTypeCourtPropertyName, oldValue, value, true);
}
}
public const string CourtCodesPropertyName = "CourtCodes";
private List<Court> _courtCodes = null;
public List<Court> CourtCodes
{
get
{
return _courtCodes;
}
set
{
if (_courtCodes == value)
{
return;
}
var oldValue = _courtCodes;
_courtCodes = value;
// Update bindings and broadcast change using GalaSoft.Utility.Messenging
RaisePropertyChanged(CourtCodesPropertyName, oldValue, value, true);
}
}
该视图具有一个DataGrid:
The View has a DataGrid:
<DataGrid
ItemsSource="{Binding CourtCodes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="False"
AlternatingRowBackground="{DynamicResource OffsetBrown}"
AlternationCount="1" Margin="45,0">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Abbreviation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Header="Abbreviation"
Width="25*" />
<DataGridTextColumn Binding="{Binding FullName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Header="Court"
Width="75*" />
<DataGridComboBoxColumn Header="CourtType"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CourtCodesTypeCourt} TextBinding="{Binding CourtTypeDescription}""/>
</DataGrid.Columns>
</DataGrid>
如您所见,DataGrid具有ItemsCodes的ItemsSource.我希望CourtType列是包含在CourtCodesTypeCourt中的所有枚举CourtType的下拉列表.在我的一生中,我似乎无法用任何东西填充DataGridComboBoxColumn.当前失败的尝试是希望使用RelativeSource ...我在做什么错了?
The DataGrid has an ItemsSource, as you can see, of CourtCodes. I want the CourtType column to be a drop down of all enumerated CourtTypes that are contained within CourtCodesTypeCourt. For the life of me, I can't seem to populate the DataGridComboBoxColumn with anything. The current failed attempt is looking to use RelativeSource... what am I doing wrong?
除了无法正常工作外,我看到的两个错误是:
In addition to not working, the two errors I see are:
System.Windows.Data错误:4:无法 查找参考的绑定来源 'RelativeSource FindAncestor, AncestorType ='System.Windows.Window', AncestorLevel ='1''. BindingExpression:Path = DataContext.CourtCodesTypeCourt; DataItem = null;目标元素是 'DataGridComboBoxColumn' (HashCode = 38771709);目标物业 是"ItemsSource"(类型为"IEnumerable")
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=DataContext.CourtCodesTypeCourt; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=38771709); target property is 'ItemsSource' (type 'IEnumerable')
和
System.Windows.Data错误:40: BindingExpression路径错误: 'CourtCodesTypeCourt'属性不是 在对象"法院"上找到 (HashCode = 38141773)". BindingExpression:Path = CourtCodesTypeCourt.CourtTypeDescription; DataItem ='法院'(HashCode = 38141773); 目标元素是"ComboBox" (名称='');目标属性是文本" (类型为字符串")
System.Windows.Data Error: 40 : BindingExpression path error: 'CourtCodesTypeCourt' property not found on 'object' ''Court' (HashCode=38141773)'. BindingExpression:Path=CourtCodesTypeCourt.CourtTypeDescription; DataItem='Court' (HashCode=38141773); target element is 'ComboBox' (Name=''); target property is 'Text' (type 'String')
推荐答案
DataGrid
列定义不按照您期望的方式参与逻辑树.这太荒谬了,但最后我检查了您是否必须执行以下操作:
DataGrid
column definitions don't participate in the logical tree in the way you would expect. It's ridiculous, but last I checked you have to do something like this:
<DataGridComboBoxColumn Header="CourtType" SelectedItemBinding="{Binding Type}">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CourtCodesTypeCourt}"/>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CourtCodesTypeCourt}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
您会注意到我也将您的TextBinding
更改为SelectedItemBinding
.我不确定您是否确实打算使用TextBinding
,但是如果您只想允许用户在列表之间进行选择,那么SelectedItemBinding
可能就是您想要的.
You'll notice I've also changed your TextBinding
to a SelectedItemBinding
. I'm not sure if you actually intended a TextBinding
, but if you just want to allow the user to select between the list, then SelectedItemBinding
is likely what you want.
此外,您的VM并不完全遵循最佳实践.您使用的是List<T>
而不是ObservableCollection<T>
,并且将其公开为List<T>
,而不是像ICollection<T>
这样的简单名称.
Also, your VMs don't exactly follow best practices. You're using List<T>
instead of ObservableCollection<T>
, and you're exposing it as List<T>
rather than something simpler such as ICollection<T>
.
这篇关于将WPF DataGridComboBoxColumn与MVVM一起使用-绑定到ViewModel中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!