Связывание WPF DataGrid с данными - PullRequest
6 голосов
/ 31 июля 2010

Это сводит меня с ума. Я создаю DataGrid в коде, а затем связываю его с данными. Это динамично, и строки и столбцы будут отличаться при каждом создании сетки.

По сути, я перебираю свою таблицу данных и создаю столбцы DataGrid для каждого столбца, например:

private static void CreateDataGridColumns(DataGrid datagrid, Document doc)
{
    if (doc == null) return; //return 

    datagrid.Columns.Clear();
    foreach (var item in doc.Keys)
    {
        var column = new DataGridTemplateColumn
        {
           Header = item,
           CellTemplateSelector = new CustomRowDataTemplateSelector(),
         };

        datagrid.Columns.Add(column);
    }
}

Как видите, я использую пользовательский селектор шаблонов данных, поэтому могу отображать ячейку по-разному в зависимости от ее содержимого.

Вот селектор шаблонов

public class CustomRowDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate
        SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        var presenter = container as ContentPresenter;
        var gridCell = presenter.Parent as DataGridCell;

        if (element != null && item != null && gridCell != null)
        {
            var row = item as DataRow;

            if (row != null)
            {
                var cellObject = row[gridCell.Column.DisplayIndex];

                //set template based on cell type

                if (cellObject is DateTime)
                {
                    return element.FindResource("dateCell") as DataTemplate;
                }

                return element.FindResource("stringCell") as DataTemplate;
            }


        }

        return null;
    }
}

Вот моя строка DataCemplate

<DataTemplate x:Key="stringCell">
    <StackPanel>
        <TextBlock Style="{StaticResource cellStyle}" 
                    Grid.Row="0" Grid.Column="0" 
                    Text="{Binding Converter={StaticResource cellConverter}}" />
    </StackPanel>
</DataTemplate>

Проблема в том, что селектор шаблона вызывается для каждой ячейки (как и ожидалось), но я не могу сказать, какая это ячейка, поэтому я не знаю, как установить текст в TextBlock. Я хотел бы сделать что-то вроде этого

<DataTemplate x:Key="stringCell">
    <StackPanel>
        <TextBlock Style="{StaticResource cellStyle}" 
                    Grid.Row="0" Grid.Column="0" 
                    Text="{Binding Path=Row[CellIndex], Converter={StaticResource cellConverter}}" />
    </StackPanel>
</DataTemplate>

Но я ничего не могу получить, чтобы получить CellIndex. Как я могу сделать что-то похожее на это, где я могу установить Path = Row [CellIndex]

Ответы [ 2 ]

0 голосов
/ 11 июля 2016

Вы можете попытаться создать привязку в коде. Примерно так должно работать

var bind = new Binding(gridCell.Column.Header.ToString())
bind.Mode = BindingMode.TwoWay;
bind.Source = row;
BindingOperations.SetBinding(YourTextBlock, TextBlock.TextProperty, bind);
0 голосов
/ 23 июля 2011

Не уверен, что вы пытаетесь достичь функционально. Вы можете сойти с рук в коде. Создайте класс более высокого уровня, CellClass, который имеет свойство DisplayValue. С реализацией для даты и строки. Привязать источник к CellClass с помощью Path = DisplayValue. Вы даже можете создавать списки CellClass и Bind to CellClass [0], CellClass [1] ... Я знаю, что это работает так, как я, но я не уверен, обеспечивает ли это требуемую функциональность.

    public abstract class CellClass
    {
         public abstract String DispValue { get; }
    }
    public class CellClassDate : CellClass
    {
         public override String DispValue { get ...; }
         public DateTime DateValue { get .. set ... }
    }
    public class CellClassString : CellClass
    {
         public override String DispValue { get ...; }
         public DateTime StringValue { get .. set ... }
    }
...