2014-06-04 4 views
0

이 변환기가 있습니다. 현재 DataGridCell, DataGridCellInfo 개체가 있는데 거기에 DataGrid 개체를 가져 오는 중입니다.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; 대상 요소는 'DataGridCell'(Name = ''); 속성 (유형 '부울')이 DataGridCell 아래 계산기에

DataGridCellInfo에 캐스팅 'IsTextMatchFocused', 그리고 기본적으로 내가이 일치하는지 두 DataGridCellInfo의 행과 열 인덱스를 비교하고있어 대상, 그렇다면 true를 반환합니다.

이렇게하려면 DataGrid 개체가 필요합니다. 3 가지 가능한 솔루션을 볼 수 있습니다.
1. DataGrid 개체를 사용하지 않고도 두 DataGridCellInfo 개체를 비교하여 같음을 확인할 수 있습니다. (이 시도했지만 항상 false를 반환합니다)
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

당신이 계산기로 데이터 그리드에 통과해야합니까, 아니면 그냥 부모 (또는 다른) 속성을 통해 포함하는 데이터 그리드를 얻기 위해 DataGridCell을 사용할 수 있습니다 : 당신은 한 번 컨버터 내에서 전화를? – GEEF

+0

@VP. 둘 중 누구라도 괜찮습니다. 만약 당신이 하나 또는 다른 방법을 알고 있으면 게시하십시오. – Hank

+0

아래에 답변을 추가하고 엿보기 만하십시오. – GEEF

답변

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); 
+0

죄송합니다. 다음과 같은 모든 셀에서 실패했습니다. PresentationCore.dll에서 'System.ArgumentNullException'유형의 첫 번째 예외가 발생했습니다. SelectedSearchValueConverter 오류 : 값을 null로 설정할 수 없습니다. 매개 변수 이름 : 요소 – Hank

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> 
+0

감사합니다 그러나 난 여전히 아래에 코멘트에 오류가 점점. 이유는 가상화 된 DataGrid에서 연결이 끊긴 (재활용 된) 항목이라고 생각합니다. – Hank

+0

System.Windows.Data 경고 : 4 : 'RelativeSource FindAncestor, AncestorType ='System.Windows.Controls.DataGrid ', AncestorLevel ='1 ''참조로 바인딩 소스를 찾을 수 없습니다.BindingExpression : 경로 =; DataItem = null; 대상 요소는 'DataGridCell'(Name = ''); 'IsTextMatchFocused'(유형 '부울') – Hank