简体   繁体   English

背后带有代码的DataTemplate

[英]DataTemplate with Converter in Code Behind

I'm trying to load a DataTemplate in code-behind, but it works fine if I remove the Converter... but as soon as I put it in there, it blows. 我正在尝试在代码隐藏区中加载DataTemplate,但是如果我删除Converter,它可以正常工作……但是,一旦将其放入其中,它就会崩溃。 Now, I did set my state my namespace and placed the reference to my converter in XAML. 现在,我确实将状态设置为名称空间,并在XAML中放置了对转换器的引用。 for example: 例如:

<Window.Resources>
     <local:StatCellConverter x:Key="myConverter" />
</Window.Resources>

and this is my method where I generate a DataTemplate: 这是我生成DataTemplate的方法:

private DataTemplate GenerateStatRowDataTemplate()
{
    ParserContext pc = new ParserContext();
    pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
    pc.XmlnsDictionary.Add("xcdg", "http://schemas.xceed.com/wpf/xaml/datagrid");

    string statRowTemplate = "<DataTemplate><xcdg:StatRow>";
    statRowTemplate += "<xcdg:StatCell FieldName=\"Column4\" ResultPropertyName=\"AvgColumn4\">";
    statRowTemplate += "<xcdg:StatCell.ContentTemplate>";
    statRowTemplate += "<DataTemplate>";
    statRowTemplate += "<TextBlock Text=\"{Binding ., Converter={StaticResource ResourceKey=myConverter}}\" />";
    statRowTemplate += "</DataTemplate>";
    statRowTemplate += "</xcdg:StatCell.ContentTemplate>";
    statRowTemplate += "</xcdg:StatCell>";
    statRowTemplate += "</xcdg:StatRow>";
    statRowTemplate += "</DataTemplate>";

    StringReader stringReader = new StringReader(statRowTemplate);
    XmlReader xmlReader = XmlReader.Create(stringReader);
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(statRowTemplate.ToString()));
    DataTemplate dt = (DataTemplate)XamlReader.Load(ms,pc);
    dt.LoadContent();
    return dt;
}

What am i doing wrong? 我究竟做错了什么? Could it be that I would have to define my converter in code behind as well? 难道我也必须在后面的代码中定义转换器吗?

My Converter 我的转换器

public class StatCellConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Debug.WriteLine(value);

            if (value.Equals("#DIV/0#"))
                return "0";
            return value;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

I get an exception saying that it cannot load the DataTemplate 我得到一个异常,说它无法加载DataTemplate

This in fact is a bug in the framework. 实际上,这是框架中的错误。 Adding the local name space through the XmlnsDictionary wouldn't work. 通过XmlnsDictionary添加本地名称空间将不起作用。 It has to be added within the template definition with the assembly and namespace defined: 必须使用定义的程序集和名称空间将其添加到模板定义中:

as in the comment above by @Nerd In Training this should work: 就像@Nerd In Training的评论一样,它应该可以工作:

string statRowTemplate = "<DataTemplate >"; 

private DataTemplate GenerateStatRowDataTemplate()
{
    ParserContext pc = new ParserContext();
    pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
    pc.XmlnsDictionary.Add("xcdg", "http://schemas.xceed.com/wpf/xaml/datagrid");

    string statRowTemplate = "<DataTemplate xmlns:local=\"clr-namespace:MyTest;assembly=MyTest\" ><xcdg:StatRow>";
    statRowTemplate += "<xcdg:StatCell FieldName=\"Column4\" ResultPropertyName=\"AvgColumn4\">";
    statRowTemplate += "<xcdg:StatCell.ContentTemplate>";
    statRowTemplate += "<DataTemplate>";
    statRowTemplate += "<TextBlock Text=\"{Binding ., Converter={StaticResource ResourceKey=myConverter}}\" />";
    statRowTemplate += "</DataTemplate>";
    statRowTemplate += "</xcdg:StatCell.ContentTemplate>";
    statRowTemplate += "</xcdg:StatCell>";
    statRowTemplate += "</xcdg:StatRow>";
    statRowTemplate += "</DataTemplate>";

    StringReader stringReader = new StringReader(statRowTemplate);
    XmlReader xmlReader = XmlReader.Create(stringReader);
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(statRowTemplate.ToString()));
    DataTemplate dt = (DataTemplate)XamlReader.Load(ms,pc);
    dt.LoadContent();
    return dt;
}

The full version 完整版

    var ms = new MemoryStream(Encoding.UTF8.GetBytes(@"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                                                                     xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""                                                                             
                                                                     xmlns:c=""clr-namespace:MyApp.Converters;assembly=MyApp"">
            <DataTemplate.Resources>
                <c:MyConverter x:Key=""MyConverter""/>
            </DataTemplate.Resources>
            <TextBlock Text=""{Binding ., Converter={StaticResource MyConverter}}""/>
          </DataTemplate>"));
    var template = (DataTemplate)XamlReader.Load(ms);

    var cb = new ComboBox { };
    //Set the data template
    cb.ItemTemplate = template;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM