Preselection in WPF-DataGrid with MVVM

本文关键字:MVVM with WPF-DataGrid in Preselection | 更新日期: 2023-09-27 18:16:07

我已经得到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;
    }

Preselection in WPF-DataGrid with MVVM

发生的事情是你的VM在窗口初始化之前被分配给数据上下文,因此永远不会收到CurrentItem已经改变的消息,因为它在加载之前已经改变了。

我所做的是将视图模型传递到view的构造函数中,并在调用InitializeComponent()函数后设置它。因为我正在使用Prism,所以我使用了控制反转(IOC), Prism知道将我的VM输入到构造函数中。如果你自己实例化你的视图和视图模型,你可以传入视图模型。我遇到了同样的问题,这个工作

    public MyView(IMyVM viewModel)
    {
        InitializeComponent();
        this.DataContext = viewModel;
    }

顺便说一下,在使用MVVM时,我认为没有理由不将ViewModel传递给视图,因为视图无论如何都依赖于它。我知道有些人有不同的感觉,但要么这样,要么你必须在Window_Loaded事件中刷新数据上下文