DataGridTemplateColumns, AutoGenerateColumns=true and binding to a DataTable

↘锁芯ラ 提交于 2019-12-01 21:58:18

Dusan's answer set me on the right track. Because I don't know the column names until runtime, I have to create the data template at runtime too. It's actually not difficult.

private DataTemplate GetDataTemplate(string columnName)
{
    string xaml = "<DataTemplate><ComboBox SelectedValue=\"{Binding Path=[" + columnName +
                  "].SelectedEnumeratedElementItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"" +
                  " ItemsSource=\"{Binding Path=[" + columnName +
                  "].Items}\" DisplayMemberPath=\"Name\"/></DataTemplate>";

    var sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
    var 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");
    var datatemplate = (DataTemplate)XamlReader.Load(sr, pc);

    return datatemplate;
}
ISens

I dont know how to do this with DataTemplate from XAML resources, but it work fine for me with DataTemplate created in code.

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    System.Windows.Controls.DataGridTemplateColumn templateColumn = new System.Windows.Controls.DataGridTemplateColumn();
    templateColumn.Header = e.PropertyName;

    DataTemplate template = new DataTemplate();
    FrameworkElementFactory factory = new FrameworkElementFactory(typeof(StackPanel));
    template.VisualTree = factory;
    FrameworkElementFactory childFactory = new FrameworkElementFactory(typeof(TextBox));
    childFactory.SetBinding(TextBox.TextProperty, new Binding(e.PropertyName));
    factory.AppendChild(childFactory);

    templateColumn.CellEditingTemplate = template;

    template = new DataTemplate();
    factory = new FrameworkElementFactory(typeof(StackPanel));
    template.VisualTree = factory;
    childFactory = new FrameworkElementFactory(typeof(TextBlock));
    childFactory.SetBinding(TextBlock.TextProperty, new Binding(e.PropertyName));
    factory.AppendChild(childFactory);
    templateColumn.CellTemplate = template;

    e.Column = templateColumn;
}

Modify your XAML to:

<DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn" CanUserAddRows="False" x:Name="TheDataGrid" ItemsSource="{Binding Data}">
    <DataGrid.Resources>
        <DataTemplate x:Key="dataItemCellTemplate">
            <ComboBox ItemsSource="{Binding [Option].Options}" SelectedValue="{Binding [Option].SelectedOption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
    </DataGrid.Resources>
</DataGrid>

Where [Option] refers to the column of DataView in which you store your custom DataItem objects.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!