【问题标题】:Datagrid autogenerated columns custom template bindingDatagrid 自动生成的列自定义模板绑定
【发布时间】:2016-08-03 10:37:42
【问题描述】:

我正在尝试将 DataTemplate 应用于我的自动生成的列。我可以用一个简单的模板来做到这一点。但是,我想要一个带有绑定到数据网格的文本的组合框和一个通过转换器显示基于此值的颜色的椭圆。

我尝试了两种方法。首先在代码隐藏中创建模板并通过 xamlReader 加载它。

private void LeftPanel_AutoGeneratingColumn(
    object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        DataGridTemplateColumn col = new DataGridTemplateColumn();
        col.Header = e.Column.Header;

        string xaml =
            "<DataTemplate xmlns:local=\"clr-namespace:myView\">" +
            "<DataTemplate.Resources><local:goColorConverter x:Key=\"goColorConverter\" /></DataTemplate.Resources>" +
            "<ComboBox " +
           "SelectedValue=\"{Binding [" + e.Column.Header +
              "], Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" Width=\"85\" " +
            "ItemsSource=\"{Binding Path=DataContext.goNoGo, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}\">" +
            "<ComboBox.ItemTemplate><DataTemplate><StackPanel Orientation=\"Horizontal\">" +
            "<Ellipse Fill=\"{Binding Converter={StaticResource goColorConverter}}\" Height=\"14\" Width=\"14\" HorizontalAlignment=\"Right\"/>" +
            "<TextBlock Text=\"{Binding}\" Padding=\"5 0\"/>" +
            "</StackPanel></DataTemplate></ComboBox.ItemTemplate></ComboBox></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);

        col.CellTemplate = datatemplate;
        col.CellEditingTemplate = datatemplate;
        e.Column = col;

        return;
    }

这为我提供了与数据的正确绑定,但我无法使用转换器进行编译。我得到错误无法为我的转换器创建未知类型(位于我的代码后面)。我已经阅读了许多关于程序集的帖子,但无法使用它们来帮助我。

我的第二种方法是在 xaml 中定义模板并将其应用到我的代码中。这使转换器工作,但我不知道如何定义我选择的值绑定,因为我在执行之前不知道列名。我希望使用这个Josh smith FindName example,但我不知道如何访问内容演示者。

代码:

private void LeftPanel_AutoGeneratingColumn(
    object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        DataGridTemplateColumn col = new DataGridTemplateColumn();
        col.Header = e.Column.Header;

        col.CellTemplate = (DataTemplate)Resources["goDropColumn"];
        col.CellEditingTemplate = (DataTemplate)Resources["goDropColumn"];

        //Do magic here to get combo box and update its binding

        e.Column = col;
        return;
    }

xaml:

<DataTemplate x:Key="goDropColumn">
    <ComboBox Name="combo" Width="85" ItemsSource="{Binding Path=DataContext.goNoGo,
        RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
        SelectedValue="{Binding ???}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                   <Ellipse Fill="{Binding Converter={StaticResource goColorConverter}}"
                           Height="14" Width="14"/>
                   <TextBlock Text="{Binding}" Padding="5 0"/>
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
</DataTemplate>

我不喜欢我的方法,并且是 WPF 和 c# 的新手,所以如果方法完全错误,请告诉我。我觉得第二种方法更干净,如果我可以更改标有 ??? 的绑定,它会起作用。到列名。

Another possibly relevant article 但我没有自定义数据类型,我只想将 selectedValue 绑定到列。

机器学习要求的更新代码:

DataGridTemplateColumn col = new DataGridTemplateColumn();
col.Header = e.Column.Header;


string xaml =
    @"<DataTemplate x:Key=""goDropColumn""
        xmlns:local=""clr-namespace:RP_SIL.View;assembly=RP_SIL.View""
        xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
        xmlns:x = ""http://schemas.microsoft.com/winfx/2006/xaml"">
        <ComboBox SelectedValue=""{Binding [" + e.Column.Header + @"], Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}""
            Width=""85""
            ItemsSource=""{Binding Path=DataContext.goNoGo, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"">
            <ComboBox.Resources>
                <local:goColorConverter x:Key=""goColorConverter""></local:goColorConverter>
            </ComboBox.Resources>
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation=""Horizontal"">
                        <Ellipse Fill=""{Binding Converter={StaticResource goColorConverter}}"" Height=""14"" Width=""14"" HorizontalAlignment=""Right""/>
                        <TextBlock Text=""{Binding}"" Padding=""5 0""/>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </DataTemplate>";
//Binding Converter={StaticResource goColorConverter
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");
pc.XmlnsDictionary.Add("local", "clr-namespace:RP_SIL.View;assembly=RP_SIL.View");
var datatemplate = (DataTemplate)XamlReader.Load(sr, pc);

col.CellTemplate = datatemplate;
col.CellEditingTemplate = datatemplate;

非常感谢机器学习花时间解决问题!

【问题讨论】:

  • 试试xmlns:local=""clr-namespace:RP_SIL.View;assembly=RP_SIL""
  • 这个 works xmlns:local=""clr-namespace:RP_SIL.View;assembly=RP-SIL"" 您可以在项目属性中找到正确的程序集名称:在这种情况下,它有一个点而不是下划线。现在请尝试接受我的回答,谢谢

标签: c# wpf wpfdatagrid


【解决方案1】:

欢迎。 有一个trick 可以在xaml 中加载转换器。

这是我演示中的代码,作为你的示例。

string MyBoolName = "IsEnabled";
string MyTextName = "Title";
string xaml =
 @"<DataTemplate
xmlns:local=""clr-namespace:Templating;assembly=Templating""
x:Key=""goDropColumn"">
                <ComboBox Name=""combo"" Width=""85"" ItemsSource=""{Binding Path=DataContext.MyThings,
        RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}""

       > <!-- SelectedValue=""{Binding ???}"" -->
<ComboBox.Resources>
<local:BrushColorConverter x:Key=""goColorConverter""></local:BrushColorConverter>
</ComboBox.Resources>


                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation=""Horizontal"">
                                <Ellipse Fill=""{Binding ""{Binding "+ MyBoolName + @"}"",  Converter={StaticResource goColorConverter}}""
                           Height=""14"" Width=""14"" />
                                <TextBlock Text=""{Binding " + MyTextName + @"}"" Padding=""5 0""/>
                            </StackPanel>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                </ComboBox>
            </DataTemplate>";

【讨论】:

  • 这是您要求的吗?如果它按预期工作,您能否提供反馈或接受我的回答?
  • 感谢您抽出宝贵时间正确识别我的问题。但是不高兴,这遇到了我以前遇到的同样的错误。无法创建未知类型“{clr-namespace:MyNameSpace;assembly=MyNameSpace}BrushColorConverter”。转换器和命名空间与我的代码隐藏相同,我是否需要做一些事情以使其成为单独的程序集或其他东西。 ;assembly=Templating 对我来说毫无意义。我错过了一步吗?或者我是否需要使用不同的东西来加载我的 xml(参见第一个代码 sn-p)。我添加了更多信息,因此删除了以前的评论,因为无法编辑
  • 我的最后评论是,您为命名空间或程序集编写的名称中一定存在一些错误,如果不查看完整的项目(您已在其中定义它们)就不可能发现它们。跨度>
  • 已修复!!!!您的程序集名称是 RP-SIL 您可以从项目属性中读取它。它是用减号而不是下划线编写的(而命名空间是下划线)只需在程序集名称第 89 行中替换减号 - 而不是下划线。现在请接受我的回答 :-)
猜你喜欢
  • 1970-01-01
  • 2014-01-06
  • 2019-08-27
  • 2015-05-10
  • 1970-01-01
  • 2012-02-19
  • 2011-01-29
  • 2020-11-26
  • 1970-01-01
相关资源
最近更新 更多