2016-09-09 25 views
1

我有一個DataGridComboBoxColumn列一個DataGrid,我需要啓用或禁用另一列複選框細胞,但我的代碼似乎並沒有工作。禁用在WPF數據網格中的單元格時,組合值設置爲一個值 - MVVM

我有下面的代碼定義我的組合列:

<DataGridComboBoxColumn Header="Location" 
SelectedValueBinding="{Binding LocationId, Mode=TwoWay}" 
SelectedValuePath="LocationId" 
DisplayMemberPath="LocationText" 
TextBinding="{Binding Location, Mode=TwoWay}"> 

,這是我的複選框列代碼:我添加了一個DataTrigger嘗試檢測時

<DataGridCheckBoxColumn Header="Active" 
Binding="{Binding IsActive}"> 
    <DataGridCheckBoxColumn.CellStyle> 
    <Style TargetType="DataGridCell"> 
     <Style.Triggers> 
     <DataTrigger Binding="{Binding SelectedLineItem.Location}" 
      Value="01"> 
      <Setter Property="IsEnabled" Value="False" /> 
     </DataTrigger>           
     </Style.Triggers> 
    </Style> 
    </DataGridCheckBoxColumn.CellStyle> 
</DataGridCheckBoxColumn> 

位置字段更改爲01,並基於此我試圖禁用所選行中的複選框單元格,但它不起作用。

我還需要檢查/取消選中基於其他值的組合。

任何想法,我可以如何實現這一目標?

更新1:

好吧,我已經取得了一些進展,其中我現在的觸發器踢,但出於某種原因,每當我在降改變位置下移選定(僥倖!)單元格,它將所有行的值更改爲相同的值。

這裏是我的下拉列全碼:

<DataGridComboBoxColumn Header="Location" 
    SelectedItemBinding="{Binding DataContext.SelectedLineItem.SelectedLocation, 
    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, 
    Mode=TwoWay}" 
    SelectedValuePath="LocationId" 
         DisplayMemberPath="LocationText" 
         TextBinding="{Binding Location, Mode=TwoWay}"> 
    <DataGridComboBoxColumn.ElementStyle> 
     <Style TargetType="{x:Type ComboBox}"> 
      <Setter Property="ItemsSource" Value="{Binding DataContext.Locations, 
      RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> 
      <Setter Property="IsReadOnly" Value="True"/> 
      <Setter Property="FontSize" Value="14"/> 
     </Style> 
    </DataGridComboBoxColumn.ElementStyle> 
    <DataGridComboBoxColumn.EditingElementStyle> 
     <Style TargetType="{x:Type ComboBox}"> 
      <Setter Property="ItemsSource" Value="{Binding DataContext.Locations, 
      RelativeSource={RelativeSource FindAncestor, 
      AncestorType={x:Type Window}}}"/> 
      <Setter Property="SelectedItem" Value="{Binding DataContext.SelectedLocation, 
      RelativeSource={RelativeSource FindAncestor, 
      AncestorType={x:Type Window}}}"/> 
      <Setter Property="IsReadOnly" Value="False"/> 
      <Setter Property="IsEditable" Value="True"/> 
      <Setter Property="FontSize" Value="14"/> 
      <EventSetter Event="KeyUp" Handler="LocationColumn_KeyUp"></EventSetter> 
      <Style.Triggers> 
       <Trigger Property="IsKeyboardFocusWithin" Value="True"> 
        <Setter Property="IsDropDownOpen" Value="true" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </DataGridComboBoxColumn.EditingElementStyle> 
</DataGridComboBoxColumn> 

這裏是我的複選框列的完整代碼(不要擔心什麼觸發器做的 - 他們是測試觸發器):

<DataGridCheckBoxColumn Header="Active" Binding="{Binding IsActive}"> 
    <DataGridCheckBoxColumn.CellStyle> 
     <Style TargetType="DataGridCell"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationId}" Value="1"> 
        <Setter Property="Background" Value="Green" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="" > 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="01" > 
        <Setter Property="IsEnabled" Value="True" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="02" > 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="03" > 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </DataGridCheckBoxColumn.CellStyle> 
</DataGridCheckBoxColumn> 

誰能弄清楚爲什麼當我改變一個組合的值我的所有行現在正在設定?

謝謝。

+0

進行裝訂可能不是你認爲它是DataContext的;它是否適用於'RelativeSource AncestorType = DataGrid'? –

+0

@EdPlunkett我已經更新了我的答案。進一步,但仍然不是100%。有任何想法嗎? – Thierry

回答

0

您正在將您的複選框綁定到SelectedLineItem.Location。但是我可以看到這個屬性沒有綁定到組合框的任何位置。您已綁定您的組合框的TextBinding到「位置」。嘗試將其更改爲SelectedILineItem.Location。然後複選框將被綁定到組合框中的類型值。

如果要根據組合框的選定值啓用/禁用複選框,您應該將組合框的SelectedValuePath綁定到此屬性,或將您的複選框綁定到SelectedItem.LocationId和觸發條件,以匹配組合框的綁定。

0

如果我明白你的問題正確,我認爲這可以試試這個方法。我在一個組合框中綁定了一個國家列表,並根據選擇的某個值禁用了另一列。

的XAML代碼看起來像

<Window.Resources> 
     <staticData:CountryList x:Key="CountryList"/> 
    </Window.Resources> 

    <Grid> 
     <DataGrid ItemsSource="{Binding SampleList}" AutoGenerateColumns="False"> 
      <DataGrid.Columns> 
       <DataGridTemplateColumn Header="Countries" Width="100"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding SelectedCountry}"/> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 

        <DataGridTemplateColumn.CellEditingTemplate> 
         <DataTemplate> 
          <ComboBox Height="22" Grid.Row="0" 
             ItemsSource="{StaticResource CountryList}" 
             SelectedItem="{Binding SelectedCountry}"> 
          </ComboBox> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellEditingTemplate> 

       </DataGridTemplateColumn> 

       <!-- Inputs --> 
       <DataGridTextColumn Width="SizeToCells" Header="Inputs" MinWidth="100" Binding="{Binding Input}" > 
        <DataGridTextColumn.CellStyle> 
         <Style TargetType="DataGridCell"> 
          <Style.Triggers> 
           <DataTrigger Binding="{Binding SelectedCountry}" Value="UK"> 
            <Setter Property="IsEnabled" Value="false"/> 
           </DataTrigger> 
          </Style.Triggers> 
         </Style> 
        </DataGridTextColumn.CellStyle> 
       </DataGridTextColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 

視圖模型具有

public class MainViewModel : ObservableObject 
    { 
     private List<SampleData> sampleList; 

     public List<SampleData> SampleList 
     { 
      get { return sampleList; } 
      set { Set(ref sampleList, value); } 
     } 

     private Country selectedItem; 

     public Country SelectedItem 
     { 
      get { return selectedItem; } 
      set { selectedItem = value; } 
     } 

     private ObservableCollection<Country> countries; 

     public ObservableCollection<Country> CountriesList 
     { 
      get { return countries; } 
      set { this.Set(ref countries, value); } 
     } 

     public MainViewModel() 
     { 
      CountriesList = new ObservableCollection<Country> { new Country { Id = 1, Name = "India" }, new Country { Id = 1, Name = "Australia" } }; 

      SampleList = new List<SampleData> 
      { 
       new SampleData 
       { 
        Input = "shan", RowNum = 3, SelectedCountry = "India" 
       }, 

       new SampleData 
       { 
        Input = "raj", RowNum = 1, SelectedCountry = "India" 
       }, 

       new SampleData 
       { 
        Input = "sfk", RowNum = 9, SelectedCountry = "India" 
       }, 

       new SampleData 
       { 
        Input = "ShanSfk", RowNum = 7, SelectedCountry = "India" 
       } 
      }; 
     } 
    } 

和列表

public class CountryList : List<string> 
    { 
     public CountryList() 
     { 
      this.Add("India"); 
      this.Add("Australia"); 
      this.Add("UK"); 
     } 
    } 

基於我國在組合框中選擇的細胞被啓用或禁用。

+0

感謝您花時間提供這樣一個詳細的樣本,但是您對組合欄使用了不同的控件類型,並且當我試圖適應您的設計時,我最終花費了更多時間來解決這個問題。如果有任何幫助,我已經用更多信息更新了我的答案。 – Thierry

1

感謝@Freeman指向正確的方向。

我最終弄明白了,我設法完全實現它的唯一方法是在XAML中設置屬性和在ViewModel中應用一些基本邏輯的組合。

下面是完整的解釋:

我有被綁定到我的SelectionLocation財產,屬於我行的ViewModel

get { return this._selectedLocation; } 
set { Set(() => SelectedLocation, ref this._selectedLocation, value); } 

現在關於DataGridComboBoxColumn在XAML綁定:

<DataGridComboBoxColumn Header="Location" 
    SelectedItemBinding="{Binding SelectedLocation, Mode=TwoWay}" 
    SelectedValuePath="LocationId" 
    DisplayMemberPath="LocationText"> 

這是我的第一個問題,因爲每當我從組合中選擇一個項目時,它都不會調用/觸發我的SelectedLocation的setter部分視圖模型。這是固定的,加入UpdateSourceTrigger=PropertyChanged

<DataGridComboBoxColumn Header="Warehouse" 
    SelectedItemBinding="{Binding SelectedLocation, Mode=TwoWay, 
          UpdateSourceTrigger=PropertyChanged}" 
    SelectedValuePath="LocationId" 
    DisplayMemberPath="LocationText"> 

關於複選框列中,XAML被定義爲:

<DataGridCheckBoxColumn Header="Active" Binding="{Binding IsActive, Mode=TwoWay> 
    <DataGridCheckBoxColumn.ElementStyle> 
     <Style TargetType="CheckBox"> 
      <Setter Property="HorizontalAlignment" Value="Center" /> 
      <Setter Property="VerticalAlignment" Value="Center" /> 
    </DataGridCheckBoxColumn.ElementStyle> 
</DataGridCheckBoxColumn> 

再次,檢查和取消選中複選框我的時候,它並不會觸發的二傳手我屬於與「SelectedLocation」屬性相同的ViewModel的IsActive屬性。

要解決這個問題,我最終加入UpdateSourceTrigger=PropertyChanged

<DataGridCheckBoxColumn Header="Active" Binding="{Binding IsActive, Mode=TwoWay, 
    UpdateSourceTrigger=PropertyChanged}"> 
    <DataGridCheckBoxColumn.ElementStyle> 
     <Style TargetType="CheckBox"> 
      <Setter Property="HorizontalAlignment" Value="Center" /> 
      <Setter Property="VerticalAlignment" Value="Center" /> 
    </DataGridCheckBoxColumn.ElementStyle> 
</DataGridCheckBoxColumn> 

現在與組合和複選框列的結合問題進行排序,一件事依然存在。有條件的選擇。這是通過使用XAML中的DataTrigger和我的ViewModel中的代碼進行排序的。

的XAML了有利的保健/禁用複選框,作爲對從SelectedLocation選擇:

<DataGridCheckBoxColumn Header="Active" Binding="{Binding IsActive, Mode=TwoWay, 
    UpdateSourceTrigger=PropertyChanged}"> 
    <DataGridCheckBoxColumn.ElementStyle> 
     <Style TargetType="CheckBox"> 
      <Setter Property="HorizontalAlignment" Value="Center" /> 
      <Setter Property="VerticalAlignment" Value="Center" /> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="01" > 
        <Setter Property="IsEnabled" Value="True" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="02" > 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="03" > 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </DataGridCheckBoxColumn.ElementStyle> 
</DataGridCheckBoxColumn> 

而且在我的ViewModel,每當SelectedLocation二傳手被觸發,它現在適用相同的規則,即檢查是否位置是01,02或03,它會設置我的IsActive財產,因此選擇/取消選擇複選框:

public LocationViewModel SelectedLocation 
{ 
    get { return this._selectedLocation; } 
    set 
    { 
     Set(() => SelectedLocation, ref this._selectedLocation, value); 
     if (this._selectedLocation.LocationText == "01") 
      this.IsActive = false; 
     else if (this._selectedLocation.LocationText == "02") 
      this.IsActive = true; 
     else if (this._selectedLocation.LocationText == "03") 
     { 
      this.IsActive = false; 
     } 
    } 
} 

這顯然是不理想,但它是作爲預期工作準確。理想的解決辦法是有IsChecked設置爲true或false基於XAML中的條件爲這樣的:

<DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="02" > 
<Setter Property="IsChecked" Value="True" /> 
<Setter Property="IsEnabled" Value="False" /> 
</DataTrigger> 

但無論出於何種原因,當我用這個方法,它會觸發IsActive二傳手當我檢查手動複選框,但它不會根據觸發器規則觸發它,從而使這個屬性無用,我不能擁有。

無論如何,我認爲就是這樣。希望這有助於其他。

UPDATE

我不得不發佈的最新情況出乎我的意料,而複選框使用

<DataGridCheckBoxColumn Header="Active" Binding="{Binding IsActive, Mode=TwoWay, 
    UpdateSourceTrigger=PropertyChanged}"> 
    <DataGridCheckBoxColumn.ElementStyle> 
     <Style TargetType="CheckBox"> 
      <Setter Property="HorizontalAlignment" Value="Center" /> 
      <Setter Property="VerticalAlignment" Value="Center" /> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="01" > 
        <Setter Property="IsEnabled" Value="True" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="02" > 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="03" > 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </DataGridCheckBoxColumn.ElementStyle> 
</DataGridCheckBoxColumn> 

它只是暫時禁用禁用。雙擊單元格實際上啓用單元格,然後重新啓用複選框!完全沒有意義讓你禁用複選框,然後在單元格進入編輯模式時重新啓用它!

無論如何,幸運的是,還有一項工作是禁用單元而不是複選框。這可以通過使用CellStyle代替ElementStyle來實現:

<DataGridCheckBoxColumn.CellStyle> 
    <Style TargetType="DataGridCell"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="01" > 
       <Setter Property="IsEnabled" Value="True" /> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="02" > 
       <Setter Property="IsEnabled" Value="False" /> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding SelectedLocation.LocationText}" Value="03" > 
       <Setter Property="IsEnabled" Value="False" /> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</DataGridCheckBoxColumn.CellStyle> 
相關問題