将 WPF DataGridComboBoxColumn 与 MVVM 结合使用 - 绑定到 ViewModel 中的属性
我正在使用优秀的 MVVM Light Toolkit。我的 ViewModel 公开:
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:
<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 有一个 ItemsSource,如您所见,是 CourtCodes。我希望 CourtType 列成为 CourtCodesTypeCourt 中包含的所有枚举 CourtType 的下拉列表。在我的一生中,我似乎无法用任何东西填充 DataGridComboBoxColumn 。当前失败的尝试正在寻求使用relativesource...我做错了什么?
除了不起作用之外,我看到的两个错误是:
System.Windows.Data 错误:4:无法 查找参考绑定源 '相对源查找祖先, AncestorType='System.Windows.Window', 祖先等级='1''。 BindingExpression:Path=DataContext.CourtCodesTypeCourt; 数据项=空;目标元素是 'DataGridComboBox列' (哈希码=38771709);目标财产 是“ItemsSource”(类型“IEnumerable”)
并且
System.Windows.Data 错误:40: BindingExpression路径错误: “CourtCodesTypeCourt”属性不 在“对象”“法庭”上找到 (哈希码=38141773)'。 BindingExpression:Path=CourtCodesTypeCourt.CourtTypeDescription; DataItem='法院'(HashCode=38141773); 目标元素是“ComboBox” (名称='');目标属性是“文本” (输入“字符串”)
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);
}
}
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>
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 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')
and
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')
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
DataGrid
列定义不会按照您期望的方式参与逻辑树。这很荒谬,但最后我检查您必须执行以下操作:您会注意到我还将您的
TextBinding
更改为SelectedItemBinding
。我不确定您是否真的想要TextBinding
,但如果您只是想让用户在列表之间进行选择,那么SelectedItemBinding
可能就是您想要的。此外,您的虚拟机并不完全遵循最佳实践。您使用的是
List
而不是ObservableCollection
,并且您将其公开为List
而不是其他东西更简单,例如ICollection
。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:You'll notice I've also changed your
TextBinding
to aSelectedItemBinding
. I'm not sure if you actually intended aTextBinding
, but if you just want to allow the user to select between the list, thenSelectedItemBinding
is likely what you want.Also, your VMs don't exactly follow best practices. You're using
List<T>
instead ofObservableCollection<T>
, and you're exposing it asList<T>
rather than something simpler such asICollection<T>
.在这里我找到了答案 http://cinch.codeplex.com/discussions/239522
对于DataGridComboBoxColumn 您必须创建 ItemsSource 的 StaticRecource,如下所示:
并将其绑定到 DataGridComboBoxColumn,如下所示:
那是因为 DataGridColumns 不是可视化树的一部分。
如果您想绑定 DataGrid 的项目集合,则必须在两种样式上设置 ItemsSource:
Here I have found answer http://cinch.codeplex.com/discussions/239522
For the DataGridComboBoxColumn you have to create a StaticRecource of the ItemsSource like:
and bind it to the DataGridComboBoxColumn with following:
Thats because the DataGridColumns are not a part of the visual tree.
And if you want to bind on a collection of a item of the DataGrid you have to set the ItemsSource over the two styles:
看看这个精彩的教程/示例:
https://code.msdn.microsoft.com/windowsdesktop/Best-ComboBox -教程-5cc27f82
Check out this brilliant tutorial/example:
https://code.msdn.microsoft.com/windowsdesktop/Best-ComboBox-Tutorial-5cc27f82