سؤال

لدي هذا المحول، فإنه يأخذ: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' (الاسم='');الخاصية المستهدفة هي "iStextMatchFocused" (النوع "Boolean")

في المحول الموجود أسفل DataGridCell، يتم تحويل DataGridCell إلى DataGridCellInfo، وأنا أقوم بشكل أساسي بمقارنة فهرس الصفوف والأعمدة الخاصين بـ DataGridCellInfo لمعرفة ما إذا كانا متطابقين، وإذا كان الأمر كذلك، فسيتم إرجاعه صحيحًا.

وللقيام بذلك، أحتاج إلى كائن DataGrid.أستطيع أن أرى 3 حلول ممكنة:
1.ربما يمكنني فقط مقارنة كائني DataGridCellInfo لمعرفة ما إذا كانا متماثلين، دون الحاجة إلى استخدام كائن DataGrid.(لقد جربت ذلك ولكنه دائمًا ما يُرجع خطأ)
2.احصل على DataGrid الفعلي من أحد كائنات DataGridCellInfo لأنه كائن أصل.(لا أعرف كيفية القيام بذلك).
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;
    }
}
هل كانت مفيدة؟

المحلول

على الرغم من أنني أحب الحل المقدم المتمثل في إعطائه للمحول عبر RelativeSource، إلا أنه يمكن أيضًا القيام بذلك بطريقة مختلفة.من الممكن عدم تمرير معلمة 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