2015-10-20 46 views
0

我正在使用WPF - MVVM應用程序。dataGrid列取決於另一列

我必須在空白處添加產品InvoicedataGrid

每個產品都有一個參考號refsup和一個description

當我在InvoicedataGrid中添加一行時,我選擇ComboboxColumn中的參考號,並在下一列中顯示說明。

我該怎麼做? 試圖保持MVVM模式

查看

<DataGrid x:Name="dataGridInvoice" 
      Margin="5" 
      Grid.Row="1" 
      ItemsSource="{Binding Collection}" 
      AutoGenerateColumns="False" 
      SelectedItem="{Binding Selected, Mode=TwoWay}" 
      SelectionMode="Extended" 
      SelectionUnit="FullRow" 
      AddingNewItem="dataGridInvoice_AddingNewItem"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="SuppNb" 
          Binding="{Binding suppInvNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          Width="*" /> 
     <DataGridTextColumn Header="Supplier" 
          Binding="{Binding supplier, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          Width="*" /> 
     <DataGridComboBoxColumn Header="Ref Supplier" 
           ItemsSource="{Binding Products, Mode=OneWay, Source={StaticResource supplier}}" 
           DisplayMemberPath="refsup" 
           SelectedValueBinding="{Binding refSupp}" 
           SelectedValuePath="refsup" 
           Width="*" /> 
     <DataGridTextColumn Header="Description" 
          Binding="{Binding description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          Width="*" /> 
    </DataGrid.Columns> 
</DataGrid> 

視圖模型

public class InvoiceViewModel : ViewModelBase 
{ 
    public Context ctx = new Context(); 
    public InvoiceViewModel() 
    { 
     Get(false); 
    } 

    private ObservableCollection<Invoice> collection; 
    public ObservableCollection<Invoice> Collection 
    { 
     get 
     { 
      return collection; 
     } 
     set 
     { 
      collection = value; 
      OnPropertyChanged("Collection"); 
     } 
    } 

    private Invoice _selected; 
    public Invoice Selected 
    { 
     get 
     { 
      return _selected; 
     } 
     set 
     { 
      _selected = value; 
      OnPropertyChanged("Selected"); 
     } 
    } 

    private void Get(bool loadDataFirst) 
    { 
     if (loadDataFirst) ctx.Invoices.Load(); 
     Collection = ctx.Invoices.Local; 
    } 

    private void Save() 
    { 
     ctx.SaveChanges(); 
    } 

    private void Delete() 
    { 
     var id = Selected; 
     var invoice = (from i in ctx.Invoices 
        where i.idInvoice == id.idInvoice 
        select i).SingleOrDefault(); 
     Collection.Remove(invoice); 
    } 

    private Invoice _currentItem; 
    public Invoice CurrentItem 
    { 
     get 
     { 
      return _currentItem; 
     } 
     set 
     { 
      _currentItem = value; 
      OnPropertyChanged("CurrentItem"); 
     } 
    } 

    #region "Command" 

    private ICommand saveCommand; 
    private ICommand removeCommand; 

    public ICommand SaveCommand 
    { 
     get 
     { 
      return saveCommand ?? (saveCommand = new RelayCommand(p => this.Save(), p => this.CanSave())); 
     } 
    } 

    private bool CanSave() 
    { 
     return true; 
    } 

    public ICommand DeleteCommand 
    { 
     get 
     { 
      return removeCommand ?? (removeCommand = new RelayCommand(p => this.Delete(), p => this.CanDelete())); 
     } 
    } 

    public bool CanDelete() 
    { 
     if (Selected != null) 
      return true; 
     else 
      return false; 
    } 

    #endregion 
} 

型號

public partial class product 
{ 
    public int idproduct { get; set; } 
    public string @ref { get; set; } 
    public int supplier { get; set; } 
    public string refsup { get; set; } 
    public string description { get; set; } 
    public int MOQ { get; set; } 
    public int unit { get; set; } 
    public decimal priceMOQ { get; set; } 

    public virtual foodSupplier foodSupplier { get; set; } 
    public virtual unit unit1 { get; set; } 
} 
public partial class Invoice : ViewModelBase 
{ 
    public int idInvoice { get; set; } 
    public string suppInvNumber { get; set; } 
    public Nullable<int> supplier { get; set; } 
    public string refSupp { get; set; } 
    public string description { get; set; }  

    public virtual foodSupplier foodSupplier { get; set; } 
    public virtual shop shop1 { get; set; } 
} 

回答

0

您可以創建一個DataGridTemplateColumn,它定義了CellTemplateCellEditingTemplate。 CellTemplate和CellEditingTemplate的DataTemplate中定義的控件的可見性可根據所選值切換。

但是,DataGridTemplateColumnor其他任何受支持的dataGrid列不在DataGrid的Visual樹中,因此默認情況下它不會繼承DataGrid的DataGrid。因爲它們不在同一個VisualTree中,因此任何嘗試使用RelativeSource獲取DataContext都不會起作用,因爲DataGrid不能遍歷DataGrid。

因此,有多種方法可以實現這一點;外面,我將一個演示如下:

  1. 創建FrameworkElement將繼承DataContext的,即使它們在視覺或邏輯樹不是。所以,我們可以利用這個優勢來使用。

  2. 創建ContentControl其結合ProxyElement

  3. 創建一個轉換器,其將切換控制的可見性(定義於CellTemplate或CellEditingTemplate)。

  4. 創建的代理元素可以綁定到可見性數據庫。

    <Grid> 
        <Grid.Resources> 
        <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"></FrameworkElement> 
        </Grid.Resources> 
        <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"></ContentControl> 
        <DataGrid> 
         <DataGrid.Columns> 
         <DataGridTemplateColumn> 
          <DataGridTemplateColumn.CellTemplate> 
             <DataTemplate> 
              <TextBox Visibility="{Binding Source={StaticResource ProxyElement}, Path=DataContext.refsub, Converter={StaticResource ConvertorToConvertrefsubToVisibility}}" /> 
             </DataTemplate> 
          </DataGridTemplateColumn.CellTemplate>    
         </DataGridTemplateColumn> 
         </DataGrid.Columns> 
        </DataGrid> 
    </Grid> 
    
+0

非常感謝。我會努力的。 – Cantinou