2014-06-04 31 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 ='');目標 屬性「IsTextMatchFocused」(類型「布爾」)

在DataGridCell下面的轉換器轉換爲DataGridCellInfo,和我基本上比較兩個DataGridCellInfo的行和列的索引,看看它們是否匹配,如果是的話,返回true。

爲了做到這一點,我需要DataGrid對象。我可以看到3種可能的解決方案:
1.也許我可以比較兩個DataGridCellInfo對象來查看它們是否相同,而無需使用DataGrid對象。 (我試過但總是返回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

你需要在DataGrid傳遞到轉換器,或者你可以使用DataGridCell獲得通過家長(或其他)屬性包含DataGrid的? – GEEF

+0

@VP。他們中的任何一個都很好。如果你知道一個或另一個的方式,請發佈。 – Hank

+0

剛剛在下面添加了一個答案,給它一看。 – GEEF

回答

1

雖然我不喜歡的通過的RelativeSource給它轉換給定的解決方案,它也可以做不同的方式。可能無法傳遞DataGrid參數,而是通過DataGridCell上的Parent屬性在轉換器內從DataGridCell中找到它。

要做到這一點,你需要一個家長髮現helper方法:

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錯誤:值不能爲空。 參數名稱:元素 – 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