Frage

Ich habe diesen Konverter, es dauert:die aktuelle DataGridCell, ein DataGridCellInfo-Objekt und ich versuche auch, das DataGrid-Objekt dorthin zu bringen.

    <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>

Wenn dies jedoch virtualisiert ist und Sie nach unten scrollen und die Elemente recycelt werden, wird die Bindung gelöscht und ein Fehler ausgegeben.

System.Windows.Datenwarnung:4 :Quelle für die Bindung mit kann nicht gefunden werden referenz 'ElementName = GenericDataGrid'.BindingExpression:Pfad=;Datenelement = null;zielelement ist 'DataGridCell' (Name = ");Ziel eigenschaft ist 'IsTextMatchFocused' (Typ 'Boolean')

Im Konverter unten wird die DataGridCell in eine DataGridCellInfo umgewandelt, und ich vergleiche im Grunde den Zeilen- und Spaltenindex der beiden DataGridCellInfo, um festzustellen, ob sie übereinstimmen, wenn ja, geben Sie true zurück.

Dazu benötige ich das DataGrid-Objekt.Ich kann 3 mögliche Lösungen sehen:
1.Vielleicht kann ich einfach die beiden DataGridCellInfo-Objekte vergleichen, um festzustellen, ob sie identisch sind, ohne ein DataGrid-Objekt verwenden zu müssen.(Ich habe es versucht, aber es gibt immer false zurück)
2.Rufen Sie das tatsächliche DataGrid von einem der DataGridCellInfo-Objekte ab, da es ein übergeordnetes Objekt ist.(Ich weiß nicht, wie ich das machen soll).
3.Bringen Sie die Bindung auf eine andere Weise zum Laufen.

Offensichtlich wird dieser Konverter für mehrere Zellen ausgeführt, wenn sich eine der Bindungen ändert, daher möchte ich, dass er so effizient wie möglich ist.

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;
    }
}
War es hilfreich?

Lösung

Obwohl mir die gegebene Lösung gefällt, es dem Konverter über eine relative Quelle zu geben, kann es auch anders gemacht werden.Es ist möglich, einen DataGrid-Parameter nicht zu übergeben, sondern ihn stattdessen aus der Datagridzelle zu finden, sobald er sich im Konverter befindet, über das Parent eigenschaft auf der Datagridzelle.

Dazu benötigen Sie eine Hilfsmethode zum Auffinden von Eltern:

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

Sie können diesen Code an einer wiederverwendbaren Stelle ablegen oder ihn sogar zu einer Erweiterungsmethode machen, aber so rufen Sie ihn einmal im Konverter auf:

DataGrid parentDataGrid = FindParent<DataGrid>(dataGridCell);

Andere Tipps

Ich könnte mir vorstellen, dass Sie eine verwenden könnten RelativeSource Binding um Ihre Anforderung zu erfüllen.Versuchen Sie dies:

<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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top