Как я могу привязать DataGridTemplateColumn к значению столбца вместо значения строки? - PullRequest
0 голосов
/ 05 ноября 2010

У меня есть элемент управления сеткой свойств, в котором есть много редакторов ячеек, которые автоматически применяются с помощью CellEditorTemplateSelector.Каждая строка сетки свойств связана с простым PropertyItemViewModel.

Теперь я пытаюсь повторно использовать все эти редакторы ячеек и представить их в DataGrid, чтобы иметь возможность сравнивать несколько значений объекта бок о бок.Поэтому я добавил объект PropertiesRow, который содержит список PropertyItemViewModel (такой же, как в приведенной выше таблице свойств).

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

<DataTemplate x:Key="CellDataTemplate">
    <ContentControl
         Content="{Binding Mode=OneWay}"
         ContentTemplateSelector="{StaticResource CellEditorTemplateSelector}" />            
</DataTemplate>

Однако, чтобы это работало, шаблон ожидает PropertyItemViewModel (не PropertiesRow), поэтому мне нужно каким-то образом передать его через привязку, которая выбирает правильную из PropertiesRow.PropertyItems[columnIndex].Поэтому, когда я добавляю столбцы через код, я пробовал что-то вроде этого:

void AddColumns()
{
    foreach (Property shownProperty in _ShownProperties)
    {
        _DataGrid.Columns.Add(new DataGridTemplateColumn()
        {
            Header = shownProperty.Name;
            Binding = new Binding("PropertyItems[" + index + "]");
            CellTemplate = (DataTemplate) FindResource("CellDataTemplate");
        });
    }
}

Однако DataGridTemplateColumn не имеет свойства Binding!Поэтому я попытался создать промежуточный DataTemplate для каждого столбца, но это становится очень сложным, и я чувствую, что должен быть более простой способ сделать это.

Есть предложения?

Ответы [ 2 ]

2 голосов
/ 19 октября 2012

У меня были проблемы с XAML выше, но я заставил это работать. Пришлось установить Path='' или компилятор был недоволен.

Content="{Binding Mode=OneWay, Path='',
                  RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridCell, 
                                  AncestorLevel=1}, 
                  Converter={StaticResource CellToColumnValueConverter}}"
0 голосов
/ 05 ноября 2010

Я нашел способ сделать это, который не является чистым по стандартам MVVM, потому что он напрямую работает с DataGridCells, но в противном случае он работает нормально.

Я оставил свой шаблон ячейки как есть, за исключением того, чтобы оставитьон привязан к моему объекту PropertiesRow, который не имеет указания, в каком столбце мы находимся, я привязываю, используя относительную привязку источника к родительскому DataGridCell:

<DataTemplate x:Key="CellDataTemplate">
    <ContentControl
        Content="{Binding Mode=OneWay,
     RelativeSource={RelativeSource FindAncestor, 
                              AncestorType={x:Type Controls:DataGridCell}},
     Converter={StaticResource CellToColumnValueConverter}}}"
        ContentTemplateSelector="{StaticResource CellEditorTemplateSelector}" />            
</DataTemplate>

Затем я добавил CellToColumnValueConverter, который принимает DataGridCellи преобразует его в PropertyItem, используя индекс столбца:

public class CellToColumnValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        DataGridCell cell = (DataGridCell) value;
        int displayIndex = cell.Column.DisplayIndex;
        PropertiesRow r = (PropertiesRow) cell.DataContext;
        return r.PropertyItems[displayIndex];
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
...