0

私はこのコンバーターを持っています。現在の 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' でバインディングのソースが見つかりません。バインディング式:パス=; DataItem=null; ターゲット要素は 'DataGridCell' (Name='') です。ターゲット プロパティは 'IsTextMatchFocused' (タイプ 'Boolean') です。

下のコンバーターでは、DataGridCell が DataGridCellInfo にキャストされます。基本的に、2 つの DataGridCellInfo の行と列のインデックスを比較して、一致するかどうかを確認し、一致する場合は true を返します。

これを行うには、DataGrid オブジェクトが必要です。考えられる解決策は 3
つあります。 1. DataGrid オブジェクトを使用せずに、2 つの DataGridCellInfo オブジェクトを比較して、それらが同じかどうかを確認できます。(私はこれを試しましたが、常に false を返します)
2. 親であるため、DataGridCellInfo オブジェクトの 1 つから実際の DataGrid を取得します。(これを行う方法がわからない)。
3. 別の方法でバインディングを機能させます。

明らかに、このコンバーターはバインディングの 1 つが変更されるたびに複数のセルに対して実行されるため、可能な限り効率的にしたいと考えています。

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;
    }
}
4

2 に答える 2

1

RelativeSource を介してコンバーターに渡すという特定のソリューションが気に入っていますが、別の方法で行うこともできます。DataGrid パラメーターを渡さずに、代わりに、ParentDataGridCell のプロパティを介してコンバーター内で 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);
于 2014-06-05T14:11:28.930 に答える
0

a を使用し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>
于 2014-06-05T09:27:47.790 に答える