Datagrid 保持空但 ObservableCollection 有值

Datagrid stays Empty but ObservableCollection has values

目前我正在尝试学习 WPF,但我遇到了当前问题,经过数小时的谷歌搜索并尝试自行修复它。我正在尝试显示模型省。我发现了多个类似的问题,但我无法自己解决。检查输出后,没有提到任何错误。目前 Window 仅显示空模型但没有数据,即使 Observable 集合已更新。因此,在我完全破坏对 WPF 的兴趣之前,我正在寻求帮助。

MyView

<Window x:Class="isnuaatest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:isnuaatest"
    xmlns:local1="clr-namespace:isnuaatest.Models"
    xmlns:local2="clr-namespace:isnuaatest.ViewModel"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
    <local2:MainWindowViewModel/>
</Window.DataContext>
<Grid>
    <Grid>
        <DataGrid ItemsSource="{Binding Provinces, UpdateSourceTrigger=PropertyChanged}">
        </DataGrid>
    </Grid>
    <StackPanel Width="200" Margin="50">
        <Button x:Name="OpenSaveFile" Click="OpenSaveFile_Click">OpenSaveFile</Button>
    </StackPanel>
</Grid>

My View Model

using isnuaatest.Helper;
using isnuaatest.Models;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;

namespace isnuaatest.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<Province> _province;
        public ObservableCollection<Province> Provinces
        {
            get { return this._province; }
            set
            {
                _province = value;
            }
        }
        public MainWindowViewModel() : base()
        {
            this.Provinces = new ObservableCollection<Province>();
        }

        private string _savegamePath;
        public string SavegamePath
        {
            get { return _savegamePath; }
            set { _savegamePath = value; OnPropertyChanged("SavegamePath"); GetProvinces(_savegamePath);}
        }



        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var savegamefile = this.PropertyChanged;
            if (savegamefile != null)
                savegamefile(this, new PropertyChangedEventArgs(propertyName));
        }
        public event EventHandler OnItemChanged;
        public void GetProvinces(string path)
        {
            Reader reader = new Reader();
            if (_savegamePath != null)
            {
                FileStream fs = File.OpenRead(path);
                List<Province> listofProvinces = reader.ReadTextString(fs);
                foreach (Province province in listofProvinces)
                {
                    Provinces.Add(new Province()
                    {
                        Aristocrats = province.Aristocrats,
                        Artisans = province.Artisans
                    });
                }
            }
        }
    }
}

Code Behind

using isnuaatest.Helper;
using isnuaatest.Models;
using isnuaatest.ViewModel;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace isnuaatest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindowViewModel _vm = new MainWindowViewModel();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
        private void OpenSaveFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Multiselect = false;

            dynamic result = fileDialog.ShowDialog();

            if (result == true)
            {
                _vm.SavegamePath = fileDialog.FileName;
            }
        }
    }
}

我的想法是数据上下文可能不会更新,因为数据在 Observable 集合中。如果这是真的,我该如何更新数据上下文,我已经尝试将其添加到 xaml 中,但无济于事。

谢谢

您实际上创建了 3 个不同的 MainWindowViewModel 对象 - 一个在 xaml 中,两个在代码隐藏中。您可以在 xaml 中删除一个,一旦在 MainWindow 构造函数中设置 DataContext xaml - 一个被覆盖。
但是代码隐藏中的两个对象导致了你的问题 - 你将文件加载到 _vm 对象中,但它不是 DataContext.
中保存的那个 要解决您的问题,请将 _vm 用于 DataContext 而不是新对象:

public MainWindowViewModel _vm = new MainWindowViewModel();
public MainWindow()
{
     InitializeComponent();
     DataContext = _vm;
}

更改您的省份:

public ObservableCollection<Province> Provinces
        {
            get { return this._province; }
            set
            {

                _province = value;
               OnPropertyChanged("Provinces");
            }
        }