Domanda

Ho questo convertitore, ci vuole: l'attuale dataGridell, un oggetto DataGridcellInfo e sto cercando di ottenere anche l'oggetto 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>
.

ha provato semplicemente vincolando il DataGrid come di seguito, tuttavia quando questo è virtualizzato e si scorrono verso il basso e gli elementi vengono riciclati, rilascia il rilegatura e getta un errore.

.

System.Windows.Data Avvertenza: 4: Impossibile trovare la fonte per il legame Riferimento 'elementname= GenericDataGrid'. BindingExpression: percorso=; DataItiTem= NULL; Target Element è 'DataGridell' (NAME= ''); bersaglio La proprietà è 'IstextMatchFocused' (tipo 'booleano')

Nel convertitore sotto il DataGridcell viene lanciato su un DataGridcellInfo e fondamentalmente confrontando il due indice di riga e colonna DataGridcellInfo e colonna per vedere se corrispondono, se si restituiscono True.

Per fare ciò ho bisogno dell'oggetto DataGrid. Posso vedere 3 possibili soluzioni:
1. Forse posso semplicemente confrontare i due oggetti DataGridcellInfo per vedere se sono gli stessi, senza dover usare un oggetto DataGrid. (L'ho provato ma ritorna sempre false)

2. Ottieni il DataGrid effettivo da uno degli oggetti DataGridcellInFO in quanto è un genitore. (Non so come farlo).
. 3. Ottieni il legame funzionante in un modo diverso.

Ovviamente questo convertitore verrà eseguito per più celle ogni volta che uno dei binding cambierà in modo che vorrei che sia il più efficiente possibile.

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

È stato utile?

Soluzione

Sebbene mi piace la soluzione data di darlo al convertitore tramite un relantource, può anche essere fatto un modo diverso.È possibile non passare un parametro dataGrid, ma invece trovarlo da DataGridcell una volta all'interno del convertitore tramite la proprietà Parent su DataGridcell.

Per fare ciò, avrai bisogno di un metodo di aiuto per la ricerca genitore:

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

È possibile scegliere di mettere questo codice in un punto riutilizzabile, o addirittura renderlo un metodo di estensione, ma ecco come lo chiami una volta all'interno del convertitore:

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

Altri suggerimenti

Immagino che potresti usare un RelativeSource Binding per raggiungere il vostro requisito.Prova questo:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top