【发布时间】:2020-10-06 13:55:59
【问题描述】:
经过:
WPF binding not updating the view https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged?redirectedfrom=MSDN&view=netcore-3.1
和
WPF DataContext updated but UI not updated
我仍然不明白为什么在以下情况下 UI 没有更新(我最好的猜测是要更新的 Grid 的 DataContext 没有更新)并且我正在失去理智:
AppliedJobsModel.cs(已按照某些答案的建议实施了 IPropertyChange):
public class AppliedJobsModel { }
public class AppliedJob : INotifyPropertyChanged
{
private string appliedDate;
private string url;
private string company;
private string description;
private string contact;
private string stack;
private string response;
private string interviewDate;
public AppliedJob(string[] entries)
{
appliedDate = entries[Consts.APPLIED_DATE_INDEX];
url = entries[Consts.URL_INDEX];
company = entries[Consts.COMPANY_INDEX];
description = entries[Consts.DESCRIPTION_INDEX];
contact = entries[Consts.CONTACT_INDEX];
stack = entries[Consts.STACK_INDEX];
response = entries[Consts.RESPONSE_INDEX];
interviewDate = entries[Consts.INTERVIEWDATE_INDEX];
}
public string AppliedDate
{
get {
return appliedDate;
}
set {
if (appliedDate != value)
{
appliedDate = value;
RaisePropertyChanged("AppliedDate");
}
}
}
public string Url
{
get
{
return url;
}
set
{
if (url != value)
{
url = value;
RaisePropertyChanged("Url");
}
}
}
public string Company
{
get
{
return company;
}
set
{
if (company != value)
{
company = value;
RaisePropertyChanged("Company");
}
}
}
public string Description
{
get
{
return description;
}
set
{
if (description != value)
{
description = value;
RaisePropertyChanged("Description");
}
}
}
public string Contact
{
get
{
return contact;
}
set
{
if (contact != value)
{
contact = value;
RaisePropertyChanged("Contact");
}
}
}
public string Stack
{
get
{
return stack;
}
set
{
if (stack != value)
{
stack = value;
RaisePropertyChanged("Stack");
}
}
}
public string Response
{
get
{
return response;
}
set
{
if (response != value)
{
response = value;
RaisePropertyChanged("Response");
}
}
}
public string InterviewDate
{
get
{
return interviewDate;
}
set
{
if (interviewDate != value)
{
interviewDate = value;
RaisePropertyChanged("InterviewDate");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
AppliedJobsViewModel.cs(有一个可观察的集合,在单击按钮时会正确更新(在 dbg 中)):
class AppliedJobsViewModel
{
private TexParser texParser;
public AppliedJobsViewModel() {
// TODO:
// -- do nothing here
}
public ObservableCollection<AppliedJob> AppliedJobsCollection
{
get;
set;
}
private ICommand _openTexClick;
public ICommand OpenTexClick
{
get
{
return _openTexClick ?? (_openTexClick = new CommandHandler(() => ReadAndParseTexFile(), () => CanExecute));
}
}
public bool CanExecute
{
get
{
// check if executing is allowed, i.e., validate, check if a process is running, etc.
return true;
}
}
public async Task ReadAndParseTexFile()
{
if (texParser == null)
{
texParser = new TexParser();
}
// Read file asynchronously here
await Task.Run(() => ReadFileAndUpdateUI());
}
private void ReadFileAndUpdateUI()
{
texParser.ReadTexFile();
string[][] appliedJobsArray = texParser.getCleanTable();
// Use this:
// https://rachel53461.wordpress.com/2011/09/17/wpf-grids-rowcolumn-count-properties/
// Update collection here
List<AppliedJob> appliedJobsList = createAppliedJobsListFromTable(appliedJobsArray);
AppliedJobsCollection = new ObservableCollection<AppliedJob>(appliedJobsList);
}
private List<AppliedJob> createAppliedJobsListFromTable(string[][] table)
{
List<AppliedJob> jobsList = new List<AppliedJob>();
for (int i = 0; i < table.Length; i++)
{
jobsList.Add(new AppliedJob(table[i]));
}
return jobsList;
}
}
AppliedJobsView.xaml:
<UserControl x:Class="JobTracker.Views.AppliedJobsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:JobTracker.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Name="appliedJobsGrid" Grid.Row="1" Grid.Column="1" Background="#50000000" Margin="10,10,10,10">
<ItemsControl ItemsSource = "{Binding Path = AppliedJobsCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBox Text = "{Binding Path = AppliedDate, Mode = TwoWay}" Width = "100" />
<TextBox Text = "{Binding Path = Url, Mode = TwoWay}" Width = "100" />
<TextBox Text = "{Binding Path = Company, Mode = TwoWay}" Width = "100" />
<TextBox Text = "{Binding Path = Description, Mode = TwoWay}" Width = "100" />
<TextBox Text = "{Binding Path = Contact, Mode = TwoWay}" Width = "100" />
<TextBox Text = "{Binding Path = Stack, Mode = TwoWay}" Width = "100" />
<TextBox Text = "{Binding Path = Response, Mode = TwoWay}" Width = "100" />
<TextBox Text = "{Binding Path = InterviewDate, Mode = TwoWay}" Width = "100" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
TrackerHome.xaml(主页/使用用户控件):
<Grid Grid.Row="1" Grid.Column="1">
<views:AppliedJobsView x:Name = "AppliedJobsControl" Loaded = "AppliedJobsViewControl_Loaded" />
</Grid>
TrackerHome.cs:
public TrackerHome()
{
InitializeComponent();
// Set data context here (https://stackoverflow.com/questions/12422945/how-to-bind-wpf-button-to-a-command-in-viewmodelbase)
// https://stackoverflow.com/questions/33929513/populate-a-datagrid-using-viewmodel-via-a-database
if (appliedJobsViewModel == null)
{
appliedJobsViewModel = new AppliedJobsViewModel();
}
this.DataContext = appliedJobsViewModel;
//AppliedJobControl.DataContext = appliedJobsViewModel;
}
private void AppliedJobsViewControl_Loaded(object sender, RoutedEventArgs e)
{
if (appliedJobsViewModel == null)
{
appliedJobsViewModel = new AppliedJobsViewModel();
}
AppliedJobsControl.DataContext = appliedJobsViewModel;
}
【问题讨论】:
-
什么没有更新,你怎么看它没有更新(如何重现问题)?
-
单击读取 tex 文件后,应使用许多 AppliedJob 对象更新可观察集合。这些对象应呈现在 UI 上的文本框网格中。我怀疑类似于stackoverflow.com/questions/24847062/… 的数据上下文相关问题(视图模型未在正确的时间实例化)
-
AppliedJobsCollection似乎没有引发PropertyChanged事件? -
是的,该集合根本没有得到“注意”。
标签: c# wpf debugging data-binding