2013-09-24 69 views
1

我以前的有關檢測在虛擬機屬性更改後未在深度不夠,所以我張貼這種WPF DataGrid的DataGrid的用在RowDetailsTemplate

我有喬布斯的網格。每個工作都可以有一個或多個員工。

DataGrid的RowDetailsTemplate包含另一個顯示員工的網格。因此,父網格綁定到作業列表。內部網格綁定到Job模型上的員工列表。

的工作模式:

public class Job : _Base 
{ 
    private string _JobName = string.Empty; 
    public string JobName 
    { 
     get { return _JobName; } 
     set 
     { 
      if (_JobName != value) 
      { 
       _JobName = value; 
       RaisePropertyChanged("JobName"); 
      } 
     } 
    } 

    private string _JobNumber = string.Empty; 
    public string JobNumber 
    { 
     get { return _JobNumber; } 
     set 
     { 
      if (_JobNumber != value) 
      { 
       _JobNumber = value; 
       RaisePropertyChanged("JobNumber"); 
      } 
     } 
    } 

    private ObservableCollection<Employee> _Employees; 
    public ObservableCollection<Employee> Employees 
    { 
     get { return _Employees; } 
     set 
     { 
      if (_Employees != value) 
      { 
       if (_Employees != value) 
       { 
        _Employees = value; 
        RaisePropertyChanged("Employees"); 
       } 
      } 
     } 
    } 

    private Employee _SelectedEmployee; 
    public Employee SelectedEmployee 
    { 
     get { return _SelectedEmployee; } 
     set 
     { 
      if (_SelectedEmployee != value) 
      { 
       if (_SelectedEmployee != value) 
       { 
        _SelectedEmployee = value; 
        RaisePropertyChanged("SelectedEmployee"); 
       } 
      } 
     } 
    } 

    public Job() 
    { 
     Employees = new ObservableCollection<Employee>(); 
    } 
} 

的員工模型

public class Employee : _Base 
{ 
    private string _EmployeeName = string.Empty; 
    public string EmployeeName 
    { 
     get { return _EmployeeName; } 
     set 
     { 
      if (_EmployeeName != value) 
      { 
       _EmployeeName = value; 
       RaisePropertyChanged("EmployeeName"); 
      } 
     } 
    } 

    private bool _IsChecked = false; 
    public bool IsChecked 
    { 
     get { return _IsChecked; } 
     set 
     { 
      if (_IsChecked != value) 
      { 
       _IsChecked = value; 
       RaisePropertyChanged("IsChecked"); 
      } 
     } 
    } 
}   

的XAML

<DataGrid ItemsSource="{Binding Jobs}" 
      SelectedItem="{Binding SelectedJob}" 
      AutoGenerateColumns="False"> 

    <DataGrid.Columns> 
     <DataGridTextColumn Header="Job Name" Binding="{Binding JobName}" /> 
     <DataGridTextColumn Header="Job Number" Binding="{Binding JobNumber}" /> 
    </DataGrid.Columns> 

    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 

      <StackPanel Orientation="Vertical"> 

       <DataGrid ItemsSource="{Binding Employees}" 
          SelectedItem="{Binding SelectedEmployee}" 
          AutoGenerateColumns="False"> 

        <DataGrid.Columns> 
         <DataGridCheckBoxColumn Binding="{Binding IsChecked}"/> 
         <DataGridTextColumn Binding="{Binding EmployeeName}"/> 
        </DataGrid.Columns> 

       </DataGrid> 

       <Button Margin="5" 
         Height="23" 
         Width="75" 
         HorizontalAlignment="Left" 
         Content="Remove"/> 

      </StackPanel> 


     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 

</DataGrid> 

的MainWindowViewModel

public class MainWindowViewModel : _Base 
{ 
    private ObservableCollection<Job> _Jobs; 
    public ObservableCollection<Job> Jobs 
    { 
     get { return _Jobs; } 
     set 
     { 
      if (_Jobs != value) 
      { 
       if (_Jobs != value) 
       { 
        _Jobs = value; 
        RaisePropertyChanged("Jobs"); 
       } 
      } 
     } 
    } 

    private Job _SelectedJob; 
    public Job SelectedJob 
    { 
     get { return _SelectedJob; } 
     set 
     { 
      if (_SelectedJob != value) 
      { 
       if (_SelectedJob != value) 
       { 
        _SelectedJob = value; 
        RaisePropertyChanged("SelectedJob"); 
       } 
      } 
     } 
    } 

    public MainWindowViewModel() 
    { 
     this.PropertyChanged += new PropertyChangedEventHandler(MainWindowViewModel_PropertyChanged); 
    } 

    void MainWindowViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName.Trim().ToLower() == "ischecked") 
     { 
      int x = 1; 
     } 
    } 
} 

我有幾個問題:

1)當點擊內部網格中的員工時,Job模型上的SelectedEmployee屬性不會觸發。

2)當選擇員工時,MainWindowViewModel_PropertyChanged不會觸發。

3)注意內部網格下面的按鈕。我如何將它的命令綁定到MainWindowVM?

+0

這些'selected'對象的目的是什麼?我會認真考慮在'Job'內部的'Employee'或'SelectedEmployee'中放置一個名爲'isChecked'的屬性。這些代表視圖的狀態,這將視圖邏輯與模型域相結合。 – Shoe

+0

用戶可以選中/取消選中任意數量的員工,然後單擊刪除。這就是目的 – CoderForHire

回答

1
  1. 當你有DataGrid中inside DataGrid's row,所以上面的DataGrid是某種eating up the selectionchange for the inner DataGrid。要解決此問題,您需要強制更新子DataGrid的綁定源。爲此,捕獲內部DataGrid的SelectionChanged事件並在處理程序中執行以下操作。

    private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
         DataGrid grid = e.OriginalSource as DataGrid; 
         var expression = grid.GetBindingExpression(DataGrid.SelectedItemProperty); 
         expression.UpdateSource(); 
    
        } 
    
  2. MainwindowVM沒有任何財產器isChecked這就是爲什麼它的PropertyChanged該屬性不點火。

  3. 要解決這個問題,你需要做幾件事情。問題是DataGrid單元格,並且行不會繼承DataContext,因爲它們不在其可視樹下。因此,要解決這個問題,你將不得不使用BindingProxy採取窗口的DataContext到您的按鈕在DataGrid中的rowdetails

定義如下綁定Proxy類:

public class MyBindingProxy : Freezable 
    { 
     public static readonly DependencyProperty BindingDataProperty = 
      DependencyProperty.Register("BindingData", typeof(object), 
      typeof(MyBindingProxy), new UIPropertyMetadata(null)); 

     protected override Freezable CreateInstanceCore() 
     { 
      return new MyBindingProxy(); 
     } 

     public object BindingData 
     { 
      get { return (object)GetValue(BindingDataProperty); } 
      set { SetValue(BindingDataProperty, value); } 
     } 

    } 
中的資源

現在你窗口(其中的DataGrid是)創建代理的實例和BindingData設置窗口,即MainWindowViewModel的DataContext的是:

<Window.Resources> 
    <local:MyBindingProxy x:Key="myproxy" BindingData="{Binding}" /> 
</Window.Resources> 

現在只需設定命令如下面的按鈕:

<Button Margin="5" 
    Height="23" 
    Width="75" 
    HorizontalAlignment="Left" 
    Content="Remove" 
    Command="{Binding BindingData.MyCommand, Source={StaticResource myproxy}}"/> 
+0

自從你發佈以來,我一直在關注這個問題,並且我很抱歉,但是這一切看起來都像是黑客。我不能相信,一個簡單的網格設置需要所有這些。另外,你正在談論關注事件。這不是真正的MVVM。沒有事件,綁定應該是可能的。 – CoderForHire