我已经得到DataGrid绑定到一个ObservableCollection<>在它的ViewModel:
<DataGrid ItemsSource="{Binding Path=Data}" SelectedItem="{Binding Path=CurrentItem}" />
ViewModel:
public ObservableCollection<TestModel> Data { get; set; }
private TestModel _currentItem;
public TestModel CurrentItem
{
get { return _currentItem; }
set
{
_currentItem = value;
RaisePropertyChanged("CurrentItem");
}
}
现在我想要的是,DataGrid将在表单启动时预先选择第一行。因此,我在构造函数的测试代码中放入了以下内容:
Data = new ObservableCollection<TestModel>
{
new TestModel() { Property1 = Guid.NewGuid().ToString() },
new TestModel() { Property1 = Guid.NewGuid().ToString() },
new TestModel() { Property1 = Guid.NewGuid().ToString() }
};
CurrentItem = Data[0];
显示数据,但第一行没有被网格选中。即使我将绑定设置为two - way,它也不会工作。
如果我在XAML中删除selecteitem -binding,并在Code-behind中添加以下代码,它会工作得很好:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var m = this.DataContext as MainViewModel;
grid.SelectedItem = m.CurrentItem;
}
发生的事情是你的VM在窗口初始化之前被分配给数据上下文,因此永远不会收到CurrentItem已经改变的消息,因为它在加载之前已经改变了。
我所做的是将视图模型传递到view的构造函数中,并在调用InitializeComponent()函数后设置它。因为我正在使用Prism,所以我使用了控制反转(IOC), Prism知道将我的VM输入到构造函数中。如果你自己实例化你的视图和视图模型,你可以传入视图模型。我遇到了同样的问题,这个工作
public MyView(IMyVM viewModel)
{
InitializeComponent();
this.DataContext = viewModel;
}
顺便说一下,在使用MVVM时,我认为没有理由不将ViewModel传递给视图,因为视图无论如何都依赖于它。我知道有些人有不同的感觉,但要么这样,要么你必须在Window_Loaded事件中刷新数据上下文