DataGrid를 변환기로 가져 오는 방법
-
21-12-2019 - |
문제
이 변환기를 가지고 있으며, 현재 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'. 바인딩 expression : 경로=; dataItem= null; 대상 요소는 'DataGridCell'(name= '')입니다. 표적 속성은 'ISTextMatchFocused'(유형 '부울')
DataGridCell 아래의 변환기는 DataGridCellInfo로 캐스팅되며 기본적으로 두 개의 DataGridCellInfo의 행과 열 색인을 비교하여 일치하는지 확인합니다.
이렇게하려면 DataGrid 객체가 필요합니다. 가능한 해결책을 볼 수 있습니다 :
1. DataGrid 객체를 사용하지 않고도 DataGridCellInfo 개체를 비교하여 동일한 지 확인할 수 있습니다. (나는 이것을 시도했지만 항상 거짓을 반환한다)
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;
}
}
. 해결책
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>
.