Вопрос

У меня есть этот конвертер, он требует:текущий DataGridCell, объект DataGridCellInfo, и я также пытаюсь поместить туда объект DataGrid.

    <Style TargetType="{x:Type DataGridCell}" x:Key="cellStyle" >
        <Setter Property="helpers:SearchBehaviours.IsTextMatchFocused">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource SelectedSearchValueConverter}" FallbackValue="False">
                    <Binding RelativeSource="{x:Static RelativeSource.Self}"/>
                    <Binding Source="{x:Static helpers:MyClass.Instance}" Path="CurrentCellMatch" />
                    <Binding ElementName="GenericDataGrid"/>
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>

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

Предупреждение System.Windows.Data:4:Не удается найти источник для привязки с помощью эталона «elementName = genericDataGrid».BindingExpression:Путь=;DataItem = ноль;целевой элемент — DataGridCell (Name='');Целевое свойство - это «istextmatchfocused» (тип 'boolean')

В преобразователе ниже DataGridCell преобразуется в DataGridCellInfo, и я в основном сравниваю индекс строки и столбца двух DataGridCellInfo, чтобы увидеть, совпадают ли они, и если да, то возвращаю true.

Для этого мне нужен объект DataGrid.Я вижу 3 возможных решения:
1.Возможно, я могу просто сравнить два объекта DataGridCellInfo, чтобы убедиться, что они одинаковы, без необходимости использовать объект DataGrid.(Я пробовал это, но он всегда возвращает false)
2.Получите фактический DataGrid из одного из объектов DataGridCellInfo, поскольку он является родительским.(Не знаю, как это сделать).
3.Заставьте привязку работать по-другому.

Очевидно, что этот преобразователь будет запускаться для нескольких ячеек всякий раз, когда изменится одна из привязок, поэтому я хотел бы, чтобы он был максимально эффективным.

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    try
    {
        if (values[0] == null || values[1] == null || values[2] == null)
        {
            return false;
        }

        DataGridCellInfo currentCellInfoMatch = (DataGridCellInfo)values[1];
        if (currentCellInfoMatch.Column == null)
            return false;

        DataGridCellInfo cellInfo = new DataGridCellInfo((DataGridCell)values[2]);
        if (cellInfo.Column == null)
            return false;

        DataGrid dg = (DataGrid)values[3];

        int cellInfoItemIndex = ((DataGridRow)dg.ItemContainerGenerator.ContainerFromItem(cellInfo.Item)).GetIndex();
        int cellInfoColumnIndex = cellInfo.Column.DisplayIndex;
        int currentCellInfoMatchItemIndex = ((DataGridRow)dg.ItemContainerGenerator.ContainerFromItem(currentCellInfoMatch.Item)).GetIndex();
        int currentCellInfoMatchColumnIndex = currentCellInfoMatch.Column.DisplayIndex;

        if (cellInfoItemIndex == currentCellInfoMatchItemIndex && cellInfoColumnIndex == currentCellInfoMatchColumnIndex)
            return true;

        return false;
    }
    catch (Exception ex)
    {
        Console.WriteLine("SelectedSearchValueConverter error : " + ex.Message);
        return false;
    }
}
Это было полезно?

Решение

Несмотря на то, что мне нравится данное решение придавало его преобразователю через Ructrientource, он также может быть проведен другим способом.Можно не пройти параметр DataGrid, но вместо этого найдут его из DatagridCell один раз внутри преобразователя через свойство Parent на DataGridCell.

Для этого вам понадобится метод помощника помощника родителей:

private T FindParent<T>(DependencyObject child)
    where T : DependencyObject
{
    T parent = VisualTreeHelper.GetParent(child) as T;  
    if (parent != null)
        return parent;
    else
        return FindParent<T>(parent);
}
.

Вы можете выбрать этот код в многоразовую точку или даже сделать его методом расширения, но вот как вы называете его один раз в преобразователе:

DataGrid parentDataGrid = FindParent<DataGrid>(dataGridCell);
.

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

Я предполагаю, что вы могли бы использовать RelativeSource Binding для достижения вашего требования.Попробуй это:

<Style TargetType="{x:Type DataGridCell}" x:Key="cellStyle" >
    <Setter Property="helpers:SearchBehaviours.IsTextMatchFocused">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource SelectedSearchValueConverter}" FallbackValue="False">
                <Binding RelativeSource="{x:Static RelativeSource.Self}"/>
                <Binding Source="{x:Static helpers:MyClass.Instance}" Path="CurrentCellMatch" />
<!-- ----> -->  <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGrid}}"/>
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Style>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top