Сетка данных WPF с привязкой к данным меняет горизонтальную ориентацию столбца в зависимости от типа данных

Я пытаюсь изменить горизонтальное выравнивание столбца DataGrid с привязкой к данным в зависимости от типа данных (например, Int32, float,..).

После долгих поисков в Интернете простого примера я узнал, что DataTriggers через xaml должен быть правильным вариантом для этого. Это правильно? Если да, то как мне реализовать триггер?

Я новичок в WPF и раньше использовал WindowsForms. Не может быть так сложно изменить ориентацию столбца в зависимости от типа данных? Любая помощь приветствуется!


person Chris    schedule 01.11.2013    source источник


Ответы (3)


Это может помочь - Различные представления/шаблон данных на основе переменной-члена

Другой вариант — использовать селектор DataTemplate. Просто посмотрите это руководство: http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector

person knov    schedule 01.11.2013
comment
спасибо за помощь :-) Я просмотрел обе ссылки, но не смог внедрить xaml в свою пользовательскую сетку. Я решил это с помощью кода - см. Ответ ниже. Может быть, у вас есть другое предложение о том, как сделать то же самое в xaml, когда вы видите код ниже? - person Chris; 06.11.2013
comment
Есть один трюк для сетки данных с автоматически сгенерированными столбцами. Вы можете обрабатывать событие AutoGeneratingColumn в своем коде и изменять CellTemplate для определенных столбцов. Мне не нравится такой подход, потому что я большой поклонник MVVM. ниже напишу ответ - person knov; 07.11.2013

Вы можете обработать событие AutoGeneratingColumn.

В вашем xaml добавьте:

<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="True" 
          AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn"></DataGrid>

В коде:

private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
   if (e.PropertyType == typeof (Int32))
   {
       if (e.Column != null)
       {
          var dgct = new DataGridTemplateColumn();
          var cName = e.Column.Header as string;
          var b = new Binding(cName);

          var sfactory = new FrameworkElementFactory(typeof(TextBlock));
          sfactory.SetValue(TextBlock.TextProperty, b);
          sfactory.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Right);
          var cellTemplate = new DataTemplate();
          cellTemplate.VisualTree = sfactory;
          dgct.CellTemplate = cellTemplate;

          dgct.Header = cName;
          dgct.SortMemberPath = cName;

          e.Column = dgct;
       }
   }

   ... *and so on for all your data types*

}

Вы можете проверить эти ссылки:

http://msdn.microsoft.com/en-us/library/cc903950(v=vs.95).aspx http://mareinsula.wordpress.com/2011/06/06/tips-on-wpf-autogenerating-datagrid/

person knov    schedule 07.11.2013

Хорошо, я решил это из кода. Может быть, кто-нибудь может подсказать, как я могу решить это более элегантно, используя XAML? Я искал в Интернете несколько часов, чтобы найти пример, который не слишком сложен для тех, кто плохо знаком с WPF, и просто не нашел ничего, что можно было бы успешно реализовать.

Хорошо, вот код: Имея DataTable в качестве источника данных, я добавляю следующее:

foreach (DataColumn cc in table.Columns)
{
    Type type = cc.DataType;

    Style alignStyle = new Style(typeof(Microsoft.Windows.Controls.DataGridCell));                            
    alignStyle.Setters.Add(new Setter(Microsoft.Windows.Controls.DataGridCell.VerticalAlignmentProperty, VerticalAlignment.Center));

    var column = new Microsoft.Windows.Controls.DataGridTextColumn
    {
        Header = cc.ColumnName,
        Binding = new Binding(cc.ColumnName)
    };

    if(type.Name=="Int32"){
        alignStyle.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Right));
        column.Foreground = Brushes.Red;
        column.CellStyle = alignStyle;
    }
    else if (type.Name == "DateTime")
    {
        alignStyle.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Center));
        column.Foreground = Brushes.Green;
        column.Binding.StringFormat = "{0:dd.MM.yyyy}";
        column.CellStyle = alignStyle;
    }
    else if (type.Name == "String")
    {
        alignStyle.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Left));
        column.Foreground = Brushes.Blue;
        column.CellStyle = alignStyle;
    }
    else if (type.Name == "Double")
    {
        alignStyle.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Right));
        column.Foreground = Brushes.Brown;
        column.Binding.StringFormat = "{0:F3}";
        column.CellStyle = alignStyle;
    }

    grids.Columns.Add(column);
}
person Chris    schedule 05.11.2013