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");
}
}
目前我正在尝试学习 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");
}
}