【发布时间】:2014-08-07 19:56:06
【问题描述】:
我正在开发一个大量使用数据网格的 WPF 应用程序。我有一个经常出现的情况,需要我在数据网格中使用自定义控件。当然,每一行绑定的数据都不一样。
我解决这个问题的方法是制作一个 DataGridTemplateColumn 类型的自定义控件,并向其中添加我自己的依赖项属性。然后当我需要在我的网格中使用这种列类型时,我可以在一行中完成。
自定义控件的数据上下文似乎完全不正常。
现在,我有以下代码...
DataGridCheckedComboColumn.xaml
<DataGridTemplateColumn x:Class="DataTracker.Presentation.GridControls.Views.DataGridCheckedComboColumn"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ccb="clr-namespace:CheckedComboBoxControl;assembly=CheckedComboBox"
mc:Ignorable="d">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ccb:CheckedComboBox ItemsSource="{Binding Path=ComboSource}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ccb:CheckedComboBox ItemsSource="{Binding Path=ComboSource}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
这用于后面的代码......
DataGridCheckedComboColumn.xaml.cs
namespace DataTracker.Presentation.GridControls.Views
{
/// <summary>
/// Interaction logic for DataGridCheckedComboColumn.xaml
/// </summary>
public partial class DataGridCheckedComboColumn : DataGridTemplateColumn
{
public DataGridCheckedComboColumn()
{
InitializeComponent();
}
/// <summary>
/// Gets or sets the runway data.
/// </summary>
/// <value>The runway data.</value>
public IEnumerable<Object> ComboSource
{
get
{
return (IEnumerable<Object>)this.GetValue(ComboSourceProperty);
}
set
{
this.SetValue(ComboSourceProperty, value);
}
}
private static void OnComboSourceChanged(DependencyObject dependentView, DependencyPropertyChangedEventArgs e)
{
/////////////////////////////////////////////////////////////////
// //
// This is the code I used when I was making user controls and //
// sending data to the view models //
// //
// //
// Not sure what, if anything to do here now... //
// //
/////////////////////////////////////////////////////////////////
//var control = (DataGridComboColumn)dependentView;
//var viewModel = (DataGridComboColumnViewModel)control.DataContext;
//viewModel.ComboSource = (IEnumerable<Object>)e.NewValue;
}
public static readonly DependencyProperty ComboSourceProperty =
DependencyProperty.Register("ComboSource",
typeof(IEnumerable<Object>),
typeof(DataGridCheckedComboColumn),
new FrameworkPropertyMetadata()
{
PropertyChangedCallback = OnComboSourceChanged,
BindsTwoWayByDefault = true
});
}
}
我像这样将自定义控件添加到我的数据网格中......
<gc:DataGridCheckedComboColumn ComboSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl, AncestorLevel=1}, Path=DataContext.DataVersions}" />
一切都正确呈现,但无论我通过什么数据,都没有成功。我什至对列表进行了硬编码并发送了这些列表,但没有运气。我也尝试过发送其他简单的属性,比如字符串,但也失败了。
WPF 给出以下错误。我应该指出,“GenericGridObject”是我用来填充完整数据网格的内容。
System.Windows.Data Error: 40 : BindingExpression path error: 'ComboSource' property not found on 'object' ''GenericGridObject`1' (HashCode=37030675)'. BindingExpression:Path=ComboSource; DataItem='GenericGridObject`1' (HashCode=37030675); target element is 'CheckedComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
就像我之前说的,我认为这是自定义控件的数据上下文的问题,但我似乎无法弄清楚如何强制它使用自己的类作为数据上下文而不是数据上下文整个网格。
有什么想法吗?
【问题讨论】:
-
如果您尝试重新创建此控件以查看我在说什么,您只需将
更改为 还是会出现同样的问题。 -
我认为问题在于您正在绑定到不知道 Dependancy 属性的 DataContext。我认为您需要绑定到 DataGridTemplateColumn ,您可以使用相对源来执行此操作。见stackoverflow.com/questions/1636807/…
-
如果我尝试命名根元素 (DataGridTemplateColumn),然后使用
,我会收到一条错误消息。 ...“System.Windows.Data 错误:4:找不到与引用'ElementName = myName'的绑定源”。另外 VS 中出现错误说...“无法在此范围内注册重复的名称 'myName'。”
标签: c# wpf xaml wpf-controls custom-controls