[英]MVVM WPF ViewModel DispatcherTimer not updating view?
I have a DispatcherTimer in my ViewModel that i can see firing every interval, but the view is not being updated? 我的ViewModel中有一个DispatcherTimer,可以看到每个时间间隔触发,但是视图没有更新吗?
the feed data comes from a xml url and i am trying to refresh the form every x seconds. 提要数据来自xml网址,我正在尝试每x秒刷新一次表单。 Maybe more or less lables / differnt status
也许或多或少的标签/不同的状态
heres the code snippets: 这是代码段:
ViewModel.cs ViewModel.cs
public class Nodes
{
public string name { get; set; }
public string id { get; set; }
public string status { get; set; }
public string last { get; set; }
public int level { get; set; }
public string parent { get; set; }
}
public ObservableCollection<CI> CIs
{
get;
set;
}
DispatcherTimer LogTimer;
public void LoadCIs()
{
ObservableCollection<CI> cis = new ObservableCollection<CI>();
LogTimer = new DispatcherTimer();
LogTimer.Interval = TimeSpan.FromMilliseconds(10000);
LogTimer.Tick += (s, e) =>
{
//pull node list
List<Nodes> SortedList = PopulateNodes();
foreach (Nodes Node in SortedList)
{
//create labels for all top level nodes
if (Node.level == 3)
{
cis.Add(new CI { NodeName = Node.name, NodeStatus = Node.status });
}
}
CIs = cis;
};
LogTimer.Start();
}
Model.cs Model.cs
public class CI : INotifyPropertyChanged {
private string nodeName;
private string nodeStatus;
public string NodeName {
get {
return nodeName;
}
set {
if (nodeName != value) {
nodeName = value;
RaisePropertyChanged("NodeName");
}
}
}
public string NodeStatus
{
get
{
return nodeStatus;
}
set
{
if (nodeStatus != value)
{
nodeStatus = value;
RaisePropertyChanged("NodeStatus");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
view.xaml view.xaml
<Grid>
<ItemsControl ItemsSource = "{Binding Path = CIs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Label Content = "{Binding Path = NodeName, Mode = OneWay}"
Background = "{Binding Path = NodeStatus, Mode = OneWay}"
Foreground="White"
FontFamily="Arial Black"
HorizontalContentAlignment="Center"
BorderBrush="Black"
BorderThickness="1,1,1,1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
how the form should look without timer enabled / commented out: 在不启用计时器的情况下,表单应如何显示/已注释掉:
with the timer code enabled nothing is added to grid: 启用计时器代码后,不会将任何内容添加到网格:
Thanks for looking 谢谢看
The problem: 问题:
You are changing the Collection CIs
but do not notify it is changed. 您正在更改集合
CIs
但不通知它已更改。 ObservableCollections report their changes but you're overwriting it, it will not report that. ObservableCollections报告它们的更改,但是您正在覆盖它,它不会报告。
Option 1: 选项1:
Because you use an ObservableCollection
you can add it to the bound collection directly and it will notify the UI automatically. 因为您使用的是
ObservableCollection
,所以可以将其直接添加到绑定的集合中,它将自动通知UI。 So instead of: 所以代替:
cis.Add(new CI { NodeName = Node.name, NodeStatus = Node.status });
Do this: 做这个:
CIs.Add(new CI { NodeName = Node.name, NodeStatus = Node.status });
if you do this you have to initialize CIs
first: 如果这样做,则必须首先初始化
CIs
项:
public ObservableCollection<CI> CIs
{
get;
set;
} = new ObservableCollection<CI>(); // < initialize it
Option 2: 选项2:
Add the INotifyPropertyChanged interface to the Nodes class and notify like this: 将INotifyPropertyChanged接口添加到Nodes类,并像这样进行通知:
this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( nameof( this.CIs ) ) );
in the setter of CIs
在
CIs
制定者中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.