2014-11-01 47 views
0

我對WPF非常陌生 - 請指出任何你認爲我沒有做到正確的方式。WPF - 將DataGrid ItemsSource綁定到通過單擊不同數據網格中的元素創建的CollectionViewSource

簡而言之問題: 在視圖模型,我存儲在_Adata變量,它在視圖作爲一個DataGrid表顯示正確的一些數據。 用戶可以點擊表格的任何一行,這會觸發一個動作,該動作在_Bdata變量中存儲一些數據。該變量儘管綁定到View中的另一個DataGrid,但未顯示。

現在,這是代碼。

MainWindowViewModel類看起來是這樣的:

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    // in the real implementation these are not created on the fly but fetched elsewhere 
    private ObservableCollection<A> _Adata; 
    public ObservableCollection<A> AData { get { return _Adata; } } 

    private ObservableCollection<B> _Bdata; 
    public ObservableCollection<B> BData { get { return _Bdata; } } 

    public ICollectionView AView, BView; 

    private A _currSelectedA; 
    public A CurrSelectedA 
    { 
     get { return _currSelectedA; } 
     private set 
     { 
      _currSelectedA = value; 
      OnPropertyChanged("CurrentSelectedA"); 
     } 
    } 

    private ICommand _rowClickCommand; 

    public MainWindowViewModel() 
    { 

     _rowClickCommand = new MainWindow.DelegateCommand(() => 
     { 
      // This command gets correctly executed, yet it does not produce any visible result in the View 
      var complexTypeB = new ComplexTypeB(); 
      _Bdata = new ObservableCollection<B>(complexTypeB.l); 
      BView = CollectionViewSource.GetDefaultView(_Bdata); 
     }); 

     var someComplexTypeInstance = new ComplexTypeA(); 
     _Adata = new ObservableCollection<A>(someComplexTypeInstance.l); 

     AView = CollectionViewSource.GetDefaultView(_Adata); 
     // At this point, the UI correctly shows the table 

     AView.CurrentChanged += delegate 
     { 
      _currSelectedA = (A)AView.CurrentItem; 
     }; 
    } 

    public ICommand RowClickCommand 
    { 
     get { return _rowClickCommand; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

}

DataModel包含在視圖模型中使用的類定義:

public class A { /* ... */ } 
    public class B { /* ... */ } 

    public class ComplexTypeA 
    { 
     public List<A> l = new List<A>(); 
    } 
    public class ComplexTypeB 
    { 
     public List<B> l = new List<B>(); 
    } 

MainWindow類看起來非常標準:

public class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     DataContext = new MainWindowViewModel(); 
    } 

    public class DelegateCommand : ICommand 
    { 
     private readonly Action _action; 
     public DelegateCommand(Action action) { _action = action; } 

     public bool CanExecute(object parameter) {return true; } 

     public void Execute(object parameter) { _action(); } 

     public event EventHandler CanExecuteChanged; 
     public void OnCanExecuteChanged() 
     { 
      CanExecuteChanged(this, EventArgs.Empty); 
     } 
    } 
} 

最後,這裏的MyWindow.xaml

<Window x:Class="WpfApplication.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
     xmlns:local="clr-namespace:WpfApplication" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300" 
     Title="MainWindow"> 
    <Grid d:DataContext="{d:DesignInstance Type=local:MainWindowViewModel}"> 

     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <Grid Grid.Row="0"> 
      <DataGrid 
      x:Name="ADataGrid" 
      HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      SelectedItem="{Binding CurrSelectedA, Mode=TwoWay}" 
      ItemsSource="{Binding AData}"> 
       <i:Interaction.Triggers> 
        <i:EventTrigger EventName="MouseLeftButtonUp" > 
         <i:InvokeCommandAction 
         Command="{Binding RowClickCommand}"/> 
        </i:EventTrigger> 
       </i:Interaction.Triggers> 
      </DataGrid> 
     </Grid> 

     <Grid Grid.Row="1"> 
      <DataGrid 
      x:Name="BDataGrid" 
      HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      ItemsSource="{Binding BData}"/> 
     </Grid> 

    </Grid> 
</Window> 

回答

1

你2ways達到你想要的東西: 1.

_rowClickCommand = new MainWindow.DelegateCommand(() => 
    { 
     // This command gets correctly executed, yet it does not produce any visible result in the View 
     var complexTypeB = new ComplexTypeB(); 
     _Bdata = new ObservableCollection<B>(complexTypeB.l); 
     this.NotifyPropertyChanged("BData"); //you need this because you create a new instance 
     BView = CollectionViewSource.GetDefaultView(_Bdata); 
    }); 

或而不是創建一個新的,只是做明確並添加

BData.Clear(); 
    foreach(var item in complexTypeB.l) 
    BData.Add(item); 
+0

令人驚訝的是,你釘了它。我選擇了你提出的第一個解決方案,看起來整潔的IMO。謝謝! – Jir 2014-11-01 14:27:01

+0

我總是採取第二:)如果你做了一些ICollectionView和排序和過濾,然後這種方法更容易處理 – blindmeis 2014-11-01 18:52:38

相關問題