Question

J'ai ce convertisseur, il faut :le DataGridCell actuel, un objet DataGridCellInfo et j'essaie également d'y insérer l'objet 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>

J'ai simplement essayé de lier le DataGrid comme ci-dessous, mais lorsque celui-ci est virtualisé et que vous faites défiler vers le bas et que les éléments sont recyclés, la liaison est supprimée et génère une erreur.

Avertissement System.Windows.Data :4 :Impossible de trouver la source pour la liaison avec la référence 'elementName = genericdatagrid'.BindingExpression:Chemin=;DataItem=null ;l'élément cible est 'DataGridCell' (Name='');La propriété cible est `` isTextMatchfocused '' (type «booléen»)

Dans le convertisseur ci-dessous, le DataGridCell est converti en DataGridCellInfo, et je compare essentiellement les index de ligne et de colonne des deux DataGridCellInfo pour voir s'ils correspondent, si c'est le cas, retourne vrai.

Pour ce faire, j'ai besoin de l'objet DataGrid.Je vois 3 solutions possibles :
1.Peut-être que je peux simplement comparer les deux objets DataGridCellInfo pour voir s'ils sont identiques, sans avoir à utiliser un objet DataGrid.(J'ai essayé ça mais ça renvoie toujours faux)
2.Obtenez le DataGrid réel à partir de l’un des objets DataGridCellInfo car il s’agit d’un parent.(Je ne sais pas comment faire ça).
3.Faites fonctionner la reliure d'une manière différente.

Évidemment, ce convertisseur sera exécuté pour plusieurs cellules chaque fois que l'une des liaisons change, j'aimerais donc qu'il soit aussi efficace que possible.

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;
    }
}
Était-ce utile?

La solution

Bien que j'aime la solution proposée consistant à la donner au convertisseur via un RelativeSource, cela peut également être fait d'une manière différente.Il est possible de ne pas transmettre un paramètre DataGrid, mais de le retrouver depuis le DataGridCell une fois dans le convertisseur via le Parent propriété sur DataGridCell.

Pour ce faire, vous aurez besoin d'une méthode d'aide à la recherche de parents :

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

Vous pouvez choisir de placer ce code dans un emplacement réutilisable, ou même d'en faire une méthode d'extension, mais voici comment l'appeler une fois dans le convertisseur :

DataGrid parentDataGrid = FindParent<DataGrid>(dataGridCell);

Autres conseils

J'imagine que vous pourriez utiliser un RelativeSource Binding pour réaliser votre exigence.Essaye ça:

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top