绑定到XAML中WPF DataGridCell内容的问题
我使用下面的帖子实现了绑定到动态对象列表的datagrid ITypedList方法GetItemProperties工作正常,显示一个包含我描述的所有列的网格 我使用一个定制的PropertyDescriptor并覆盖上面文章中描述的GetValue和SetValue方法,我还实现了动态对象中的TryGetMember和TrySetMember方法 所以基本上我有一个ComplexObject:dynamicObject,它有一个字段字典和一个实现ITypedList和IList的ComplexObject集合 这一切都很好,除了我将DataGrid的itemsSource绑定到集合时,单元格将显示SimpleObject类型名称,并且我实际上想要实现一个模板,以在文本块中显示SimpleObject的属性值 我使用了各种各样的方法来尝试获取底层的SimpleObject,但是没有任何效果,我总是获取行的ComplexObject。我使用的是自动生成的列,这似乎总是生成一个文本列,这可能是问题所在,但为什么我仍然不能从单元格属性中的某个位置获取基础SimpleObject 下面是我的理想解决方案,但这不起作用绑定到XAML中WPF DataGridCell内容的问题,wpf,xaml,datagrid,datagridcell,Wpf,Xaml,Datagrid,Datagridcell,我使用下面的帖子实现了绑定到动态对象列表的datagrid ITypedList方法GetItemProperties工作正常,显示一个包含我描述的所有列的网格 我使用一个定制的PropertyDescriptor并覆盖上面文章中描述的GetValue和SetValue方法,我还实现了动态对象中的TryGetMember和TrySetMember方法 所以基本上我有一个ComplexObject:dynamicObject,它有一个字段字典和一个实现ITypedList和IList的Compl
<Grid>
<Grid.Resources>
<DataTemplate x:Key="DefaultNodeTempate">
<ContentControl Content="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Content}">
<ContentControl.Resources>
<DataTemplate DataType="local:SimpleObjectType">
<TextBlock Text="{Binding Value}" />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DataTemplate>
</Grid.Resources>
<DataGrid ItemsSource="{Binding ElementName=mainWin, Path=DynamicObjects}">
<DataGrid.Resources>
<Style TargetType="DataGridCell">
<Setter Property="ContentTemplate" Value="{StaticResource DefaultNodeTempate}" />
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>
如有任何建议,将不胜感激
谢谢
Kieran因此我发现解决方案是在代码背后做一些工作 在AutoGeneratingColumn事件中,创建一个带有内容控件和自定义模板选择器的DataTemplate(我在Xaml中创建了选择器,并将其作为资源找到) 使用e.PropertyName作为路径为ContentControl的ContentProperty创建绑定 创建新的DataGridTemplateColumn并将新列CellTemplate设置为新的DataTemplate 将e.Column替换为新列,并使用该列的动态属性预处理cells-datacontext绑定 如果有人对此有任何改进,请随时分享您的想法 谢谢 编辑:根据要求,为我的解决方案提供一些示例代码 自定义模板选择器:
public class CustomDataTemplateSelector : DataTemplateSelector
{
public List<DataTemplate> Templates { get; set; }
public CustomDataTemplateSelector()
: base()
{
this.Templates = new List<DataTemplate>();
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
DataTemplate template = null;
if (item != null)
{
template = this.Templates.FirstOrDefault(t => t.DataType is Type ? (t.DataType as Type) == item.GetType() : t.DataType.ToString() == item.GetType().ToString());
}
if (template == null)
{
template = base.SelectTemplate(item, container);
}
return template;
}
}
可能有更好的方法来创建数据模板,我最近读到微软建议使用XamlReader,但我当时就是这样做的。另外,我还没有在动态类上测试过这一点,但我确信这两种方法都应该有效。hi@Kezza,你能在这里分享代码吗?我面临着类似的问题。我正试图找到一种方法,如何通过xaml中的绑定在单元级别设置单元可编辑(isReadOnly)。单元格的值为object,该对象具有属性值且可编辑。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="ParentControl">
<Grid.Resources>
<local:CustomDataTemplateSelector x:Key="MyTemplateSelector" >
<local:CustomDataTemplateSelector.Templates>
<DataTemplate DataType="{x:Type local:MyCellObject}" >
<TextBox Text="{Binding MyStringValue}" IsReadOnly="{Binding IsReadOnly}" />
</DataTemplate>
</local:CustomDataTemplateSelector.Templates>
</local:CustomDataTemplateSelector>
</Grid.Resources>
<DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" >
</DataGrid>
</Grid>
</Window>
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
// Get template selector
CustomDataTemplateSelector selector = ParentControl.FindResource("MyTemplateSelector") as CustomDataTemplateSelector;
// Create wrapping content control
FrameworkElementFactory view = new FrameworkElementFactory(typeof(ContentControl));
// set template selector
view.SetValue(ContentControl.ContentTemplateSelectorProperty, selector);
// bind to the property name
view.SetBinding(ContentControl.ContentProperty, new Binding(e.PropertyName));
// create the datatemplate
DataTemplate template = new DataTemplate { VisualTree = view };
// create the new column
DataGridTemplateColumn newColumn = new DataGridTemplateColumn { CellTemplate = template };
// set the columns and hey presto we have bound data
e.Column = newColumn;
}