我有这个转换器,它需要:当前的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:路径=; 的DataItem = NULL; target元素是'DataGridCell'(Name ='');目标 property是'IsTextMatchFocused'(类型'Boolean')
在下面的转换器中,DataGridCell被强制转换为DataGridCellInfo,我基本上比较了两个DataGridCellInfo的行和列索引,看它们是否匹配,如果是,则返回true。
为了做到这一点,我需要DataGrid对象。我可以看到3种可能的解决方案:
1.也许我可以比较两个DataGridCellInfo对象,看它们是否相同,而不必使用DataGrid对象。 (我试过这个,但它总是返回假)
2.从其中一个DataGridCellInfo对象获取实际的DataGrid,因为它是父对象。 (不知道该怎么做)。
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;
}
}
答案 0 :(得分:1)
虽然我喜欢通过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);
答案 1 :(得分:0)
我想你可以使用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>