2015-10-20 30 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