Вопрос

Я нашел коллекцию столбцов в своем DataGrid и надеялся итерации через нее, чтобы найти определенное имя столбца. Тем не менее, я не могу понять, как обратиться к атрибуту 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.

Что мне не хватает?

Это было полезно?

Решение

У WPF есть две разные, но сходные концепции, x: имя, которое используется для создания поля, которое ссылается на элемент, определенный в XAML, то есть подключение вашего кода-иминда к вашему XAML, и FrameworkElement.name, который уникально называет элемент в namescope.

Если элемент имеет свойство FrameworkElement.Name, x: имя установит это свойство на значение, приведенное в XAML. Тем не менее, есть случаи, когда полезно связывать неразмерные элементы с полями в коде, например, в вашем примере.

Смотрите этот связанный вопрос:

В WPF каковы различия между атрибутами x: имени и имени?

В качестве альтернативы вы можете определить свое собственное подключенное свойство, которое можно использовать для названия столбцов. Прилагаемое свойство определяется следующим образом:

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));
}

надеюсь, это поможет

Другие советы

Вы можете использовать запрос LINQ, чтобы найти имя заголовков столбцов DataGrid

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

где dgvreports является названием DataGrid.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top