我有这个转换器,它需要:当前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:path=; dataitem= null;目标元素是'datagridcell'(name='');目标 属性是'istextmatchfocused'(类型'boolean')

在DataGridCell下面的转换器中投射到DataGridCellInfo,我基本上比较了两个DataGridCellInfo的行和列索引,以查看它们是否匹配,如果是这样返回true。

为了执行此操作,我需要DataGrid对象。我可以看到3种可能的解决方案:
1.也许我可以比较两个DataGridCellInfo对象,看看它们是否相同,而无需使用DataGrid对象。 (我试过了这个,但它总是返回false)
2.从一个DataGridCellInfo对象中获取实际DataGrid,因为它是父级。 (不知道该怎么做)。
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;
    }
}
.

有帮助吗?

解决方案

虽然我喜欢通过扶手源给予转换器的给定解决方案,但它也可以不同的方式完成。可以不通过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