我想在wpftoolkit数据网格中显示数据,其中数据是
的集合public class Thing
{
public string Foo { get; set; }
public string Bar { get; set; }
public List<Candidate> Candidates { get; set; }
}
public class Candidate
{
public string Name { get; set; }
public CandidateType CandidateType { get; set; }
}
public enum CandidateType
{
Type1,
Type2,
Type42
}
其中Candidates列表中的候选者数量可在运行时配置。
所需的网格布局如下所示
Foo | Bar | Candidate 1 | Candidate 2 | ... | Candidate N
因此,我似乎无法为xaml中的候选项创建DataTemplate,因为绑定表达式会发生变化。
我在AutoGeneratedColumns事件中添加必要的列,如下所示:
private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
{
ViewModel vm = DataContext as ViewModel;
for (int i = 0; i < vm.LotsOfThings.First().Candidates.Count; i++)
{
string assName = Assembly.GetExecutingAssembly().GetName().Name;
ParserContext ctx = new ParserContext();
ctx.XamlTypeMapper = new XamlTypeMapper(new string[] { assName });
ctx.XamlTypeMapper.AddMappingProcessingInstruction("src", "WpfToolkitDataGridTester", assName);
ctx.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
ctx.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
ctx.XmlnsDictionary.Add("src", "clr-namespace:WpfToolkitDataGridTester;assembly=" + assName);
var template = XamlReader.Parse(@"<DataTemplate>
<DataTemplate.Resources>
<src:FooConverter x:Key='fooConverter' />
</DataTemplate.Resources>
<TextBlock
Foreground='{Binding Candidates[" + i + @"].CandidateType,Converter={StaticResource fooConverter}}'
Text='{Binding Candidates[" + i + @"].Name}' />
</DataTemplate>", ctx) as DataTemplate;
dg.Columns.Add(new DataGridTemplateColumn
{
Header = "Candidate " + (i + 1),
CellTemplate = template
});
}
}
然而,这失败了以下例外: XML命名空间'clr-namespace:WpfToolkitDataGridTester; assembly = WpfToolkitDataGridTester'中不存在标记'FooConverter'。线'3'位置'54'。
将StaticResource更改为DynamicResource不会发生任何变化。
我错过了什么?
FWIW:硬编码的数据模板
<DataTemplate x:Key="candidateTemplate">
<DataTemplate.Resources>
<src:FooConverter x:Key="fooConverter" />
</DataTemplate.Resources>
<TextBlock
Foreground="{Binding Candidates[0].CandidateType,Converter={StaticResource fooConverter}}"
Text="{Binding Candidates[0].Name}" />
</DataTemplate>
和模板列定义如此
<wpftk:DataGridTemplateColumn CellTemplate="{StaticResource candidateTemplate}" />
'有效'但显然没有产生所需的结果,因为候选人[0]是硬编码的。
答案 0 :(得分:3)
无论出于何种原因,如果我这样做,它会按预期工作......
string assName = Assembly.GetExecutingAssembly().GetName().Name;
StringBuilder sb = new StringBuilder();
sb.Append("<DataTemplate ");
sb.Append("xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' ");
sb.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' ");
sb.Append("xmlns:src='clr-namespace:WpfToolkitDataGridTester;assembly=" + assName + "' >");
sb.Append("<DataTemplate.Resources>");
sb.Append("<src:FooConverter x:Key='fooConverter' />");
sb.Append("</DataTemplate.Resources>");
sb.Append("<TextBlock ");
sb.Append("Foreground='{Binding Candidates[" + i + "].CandidateType,Converter={StaticResource fooConverter}}' ");
sb.Append("Text='{Binding Candidates[" + i + @"].Name}' />");
sb.Append("</DataTemplate>");
var template = (DataTemplate)XamlReader.Parse(sb.ToString());
答案 1 :(得分:1)
当XAML文件编译为BAML时,它引用程序集而不是内存源。由于BAML被编译到同一个程序集中,因此实际类型尚不可用。
我发现短期解决方法是暂时注释掉样式,构建项目,然后恢复样式。
然而,更持久的解决方案是将转换器移动到另一个组件。
答案 2 :(得分:0)
在较高级别(可能是FooConverter
的资源)而不是在每个DataGrid
中声明DataTemplate
一次会有帮助吗?