2017-03-05 11 views
2

的具體DataGid小區我有一個簡單DataGrid有兩列像如何禁用新行

<DataGrid ItemsSource="{Binding Commands}" CanUserAddRows="True" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Value" Binding="{Binding Value}"/> 
     <DataGridTemplateColumn Header="Command"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}"> 
         <ComboBox.ItemTemplate> 
          <DataTemplate> 
           <TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/> 
          </DataTemplate> 
         </ComboBox.ItemTemplate> 
        </ComboBox> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

我的目標是禁用與新行ComboBox細胞。下圖顯示了我的DataGrid(與兩個項目的ObservableCollection綁定),禁用標記的列。

enter image description here

我已經嘗試使用轉換器禁用ComboBox

IsEnabled="{Binding Value, Converter={StaticResource DisableConverter}}" 

但直到我進了第一列中的值轉換器沒有得到的調用。

希望有人能幫助我!

+0

是的,我正在使用MVVM,ItemConverter只是一個測試,以檢查當公司nverter被調用,應該在顯示第1列的值時啓用組合框。 – Fruchtzwerg

+0

因爲項目(視圖模型)還沒有創建 - 「新行」顯示將創建一個項目,如果我將值添加到第一列(所以我不能綁定到任何屬性,因爲沒有對象在後面)。這就是默認的DataGrid行爲,這基本上是我的問題。 – Fruchtzwerg

+0

否,因爲「新行」是對象的默認行。這個對象是在我爲DataGrid設置一個值的時刻創建的。但是我想在創建Item之前禁用ComboBox。 (圖爲兩項ObservableCollection) – Fruchtzwerg

回答

2

您可以應用以下StyleComboBox

<ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}"> 
    <ComboBox.Style> 
     <Style TargetType="ComboBox"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Path=DataContext,RelativeSource={RelativeSource AncestorType=DataGridRow}}" 
                 Value="{x:Static CollectionView.NewItemPlaceholder}"> 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ComboBox.Style> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 
+0

工程就像魅力!謝謝! – Fruchtzwerg

1

在此基礎上previous answer,你可以在Loaded事件處理

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     var dataGridRow = FindChild(dataGrid, x => 
     { 
      var element = x as DataGridRow; 
      if (element != null && element.Item == System.Windows.Data.CollectionView.NewItemPlaceholder) 
       return true; 
      else 
       return false; 
     }) as DataGridRow; 
     var combo = FindChild(dataGridRow, x => 
     { 
      return x is ComboBox; 
     }) as ComboBox; 
     combo.IsEnabled = false; 
    } 

這個幫手實現這一

public static DependencyObject FindChild(DependencyObject parent, Func<DependencyObject, bool> predicate) 
    { 
     if (parent == null) return null; 

     int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < childrenCount; i++) 
     { 
      var child = VisualTreeHelper.GetChild(parent, i); 

      if (predicate(child)) 
      { 
       return child; 
      } 
      else 
      { 
       var foundChild = FindChild(child, predicate); 
       if (foundChild != null) 
        return foundChild; 
      } 
     } 

     return null; 
    } 
+0

非常感謝您的幫助! – Fruchtzwerg

+1

感謝您的解決方案。它像預期的那樣工作。然而,這種解決方案的工作原理 - 我更喜歡@ mm8的解決方案,因爲我不需要任何代碼隱藏。 – Fruchtzwerg

+0

好的,歡迎,有趣的問題! – 2017-03-05 18:35:07