【问题标题】:Datagrid stays Empty but ObservableCollection has valuesDatagrid 保持为空,但 ObservableCollection 有值
【发布时间】:2021-04-16 14:14:39
【问题描述】:

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

我的视图

<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>

我的视图模型

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
                    });
                }
            }
        }
    }
}

代码背后

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 Collection 中。如果这是真的,我该如何更新数据上下文,我已经尝试在 xaml 中添加它,但无济于事。

谢谢

【问题讨论】:

    标签: c# wpf xaml datagrid observablecollection


    【解决方案1】:

    改变你的省份:

    public ObservableCollection<Province> Provinces
            {
                get { return this._province; }
                set
                {
    
                    _province = value;
                   OnPropertyChanged("Provinces");
                }
            }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 谢谢伙计,我从来没有想过这一点。现在可以了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多