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>
令人驚訝的是,你釘了它。我選擇了你提出的第一個解決方案,看起來整潔的IMO。謝謝! – Jir 2014-11-01 14:27:01
我總是採取第二:)如果你做了一些ICollectionView和排序和過濾,然後這種方法更容易處理 – blindmeis 2014-11-01 18:52:38