【问题标题】:cannot find Name of DataGridColumn programmatically无法以编程方式找到 DataGridColumn 的名称
【发布时间】:2011-06-03 02:11:09
【问题描述】:

我在我的数据网格中找到了 Columns 集合,并希望遍历它以找到某个列名称。但是,我不知道如何处理列的 x:Name 属性。这个 xaml 说明了我使用 DataGridTextColumn 和 DataGridTemplateColumn 的问题:

<t:DataGrid x:Name="dgEmployees" ItemsSource="{Binding Employees}" 
    AutoGenerateColumns="false" Height="300" >
    <t:DataGrid.Columns>
        <t:DataGridTextColumn x:Name="FirstName" Header="FirstName"
Binding="{Binding FirstName}" />
        <t:DataGridTemplateColumn x:Name="LastName" Header="LastName" >
            <t:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding LastName}" />
                </DataTemplate>
            </t:DataGridTemplateColumn.CellTemplate>
        </t:DataGridTemplateColumn>
    </t:DataGrid.Columns>
</t:DataGrid>

这是我的代码:

    DataGrid dg = this.dgEmployees;
    foreach (var column in dg.Columns) 
    {
        System.Console.WriteLine("name: " + (string)column.GetValue(NameProperty));
    }

在运行时,不存在任何值; column.GetValue 不返回任何内容。使用 Snoop,我确认 DataGridTextColumn 或 DataGridTemplateColumn 上没有 Name 属性。

我错过了什么?

【问题讨论】:

    标签: wpf wpfdatagrid datagridcolumn


    【解决方案1】:

    WPF 有两个不同但相似的概念,x:Name,用于创建引用在 XAML 中定义的元素的字段,即将您的代码隐藏连接到您的 XAML,以及 FrameworkElement.Name,它唯一地命名一个名称范围内的元素。

    如果元素具有 FrameworkElement.Name 属性,x:Name 会将此属性设置为 XAML 中给定的值。但是,在某些情况下,将非 FrameworkElement 元素链接到代码隐藏中的字段很有用,例如在您的示例中。

    查看这个相关问题:

    In WPF, what are the differences between the x:Name and Name attributes?

    作为替代方案,您可以定义自己的附加属性,该属性可用于命名列。附加属性定义如下:

    public class DataGridUtil
    {
    
        public static string GetName(DependencyObject obj)
        {
            return (string)obj.GetValue(NameProperty);
        }
    
        public static void SetName(DependencyObject obj, string value)
        {
            obj.SetValue(NameProperty, value);
        }
    
        public static readonly DependencyProperty NameProperty =
            DependencyProperty.RegisterAttached("Name", typeof(string), typeof(DataGridUtil), new UIPropertyMetadata(""));
    
    }
    

    然后您可以为每一列分配一个名称...

    xmlns:util="clr-namespace:WPFDataGridExamples"
    
    <t:DataGrid x:Name="dgEmployees" ItemsSource="{Binding Employees}" 
        AutoGenerateColumns="false" Height="300" >
        <t:DataGrid.Columns>
            <t:DataGridTextColumn util:DataGridUtil.Name="FirstName" Header="FirstName"
    Binding="{Binding FirstName}" />
            <t:DataGridTemplateColumn util:DataGridUtil.Name="LastName" Header="LastName" >
                <t:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding LastName}" />
                    </DataTemplate>
                </t:DataGridTemplateColumn.CellTemplate>
            </t:DataGridTemplateColumn>
        </t:DataGrid.Columns>
    </t:DataGrid>
    

    然后在代码中访问这个名字如下:

    DataGrid dg = this.dgEmployees;
    foreach (var column in dg.Columns) 
    {
        System.Console.WriteLine("name: " + DataGridUtil.GetName(column));
    }
    

    希望有帮助

    【讨论】:

    • 您的消息和链接提供信息。但我不确定他们如何回答我的问题。您是说由于 DataGridColumn 不是 FrameworkElement,因此此代码将不起作用吗?您能建议一种替代方法吗?
    • 丹尼尔,附加财产怎么样?请参阅上面我编辑的答案。
    • 科林,这对我有用。谢谢你。我想知道为什么他们没有为 DataGridColumns 制作一个“名称”DP。
    • 感谢您的出色回答,我如何在代码隐藏中使用此属性?例如,我想为此列设置名称属性:columnCollection = new ObservableCollection&lt;DataGridTextColumn&gt;(); columnCollection.Add(new DataGridTextColumn { Header = "ColumnHeader", Binding = new Binding("ColumnName)" , ??Name=????});
    • 叹息。 -(无限)Tinyflacid,我的意思是微软,因为在 DataGridColumn 类中没有包含“名称”DependencyProperty。我知道很多复杂性(相对于 WinForms)是(据说)更大的灵活性所需要的,但我怀疑他们可以在这种情况下声称 excuse。甚至 with 一个“名称”DP,背后的代码仍然需要从 XAML 中复制魔术字符串(当 MS 认为魔术字符串在 RaisePropertyChanged 调用中没问题时。SMH)。 WinForms 在 *.Designer.cs 中创建了单独的 DataGridViewTextBoxColumn 对象,其名称可以被智能感知/编译时检查。
    【解决方案2】:

    您可以使用 linq 查询来查找数据网格列标题的名称

    dgvReports.Columns.Select(a=>a.Header.ToString()).ToList()
    

    其中 dgvReports 是数据网格的名称。

    【讨论】:

      猜你喜欢
      • 2018-10-26
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 2012-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      相关资源
      最近更新 更多