在运行时创建“动态”DataTemplates

时间:2018-03-22 08:55:57

标签: wpf xaml

我目前的情况是在运行时创建DataGrid单元格的模板,因为属性名称是动态的,在设计时是未知的。例如,此处使用“ColumnName”(来自DataColumn)作为Binding获取颜色以填充椭圆的路径:

ts_config

有什么方法可以实现相同的但是我的DataTemplate在ResourceDictionary而不是代码背后?能够以通常的方式编辑模板会更加可取。

感谢。

2 个答案:

答案 0 :(得分:0)

动态创建单元格模板的一种方法是为您的单元格模板设置ContentControl,并在Style.Triggers内为ContentControl设置多个DataTriggers来检查属性(在您的情况下) " ColumnName")。

从那里,您可以将template的{​​{1}}属性设置为您选择的任何ContentControl,并将其存储在ControlTemplate

<强> XAML:

ResourceDictionary

答案 1 :(得分:0)

XAML是XML,因此您可以这样操作它,或者您可以将其作为字符串加载并使用字符串操作。 一旦它被编译成baml,这有点令人讨厌。 但是资源字典可以从&#34; flat&#34;未编译的文件。 如果localappdata可以使用未编译的资源字典并对其进行操作。 有很多样本在这里链接到这样的事情: https://social.technet.microsoft.com/wiki/contents/articles/28797.wpf-dynamic-xaml.aspx

或者您可以在txt文件中包含一段xaml并对其进行操作。 在我正在处理的套件中,我有一个包含以下内容的txt文件:

    <?xml version="1.0" encoding="utf-8" ?>
<DataGridTextColumn Binding="{Binding Factor[^^^Index^^^], Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"  
 xmlns:ui="clr-namespace:UILib;assembly=UILib"
 xmlns:local="clr-namespace:ScenarioEditor"
 xmlns:model="clr-namespace:ModelLib;assembly=ModelLib"
>

        <DataGridTextColumn.HeaderTemplate>
            <DataTemplate>
                <ui:IconParent Height="20" Width="30" 
                        ui:IconParent.IPType="{x:Static model:UnitTypes.^^^EnumString^^^}"
                        ui:Icon.UnitType="{x:Static model:UnitTypes.^^^EnumString^^^}"
                        ui:Icon.Side="{Binding DataContext.DefenderSide
                            , RelativeSource={RelativeSource AncestorType=UserControl}}"
                        >
                    <ui:IconParent.ToolTip>
                        <ToolTip>
                            ^^^EnumDescription^^^
                        </ToolTip>
                    </ui:IconParent.ToolTip>
                        <ui:UnitIcon Margin="2"/>
                </ui:IconParent>
            </DataTemplate>
        </DataGridTextColumn.HeaderTemplate>
    </DataGridTextColumn>

然后我使用以下代码构建数据网格:

XElement col = GetXElement(@"pack://application:,,,/Views/AttackFactors/attackFactorColumn.txt");
foreach (UnitTypes ut in  Enum.GetValues(typeof(UnitTypes)).Cast<UnitTypes>().Where(x=>x.ThisFights()==true).Select(x=>x).ToList())
{
    XElement el = new XElement(col);
    string colString = el.ToString()
        .Replace("^^^Index^^^", ((int)ut).ToString())
        .Replace("^^^EnumString^^^", ut.ToString())
        .Replace("^^^EnumDescription^^^", ut.ToDescriptionString());
    ParserContext context = new ParserContext();
    context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
    DataGridTextColumn tc = (DataGridTextColumn)XamlReader.Parse(colString, context);
    dg.Columns.Add(tc);
};

您可以扩展该原则以构建在设计时合并的资源字典,以便您可以看到对设计时数据的影响。

仅设计时间资源字典: https://github.com/jbe2277/waf/wiki/WPF-Design-Time-Support-(Part-2)