我在ViewModel中有一个DispatcherTimer,可以看到每个时间间隔触发一次,但是视图没有更新?
提要数据来自xml网址,我正在尝试每x秒刷新一次表单。也许或多或少的标签/不同的状态
此处是代码段:
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
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
<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>
未启用计时器/已注释掉表单的外观:
启用计时器代码后,不会将任何内容添加到网格:
感谢您的光临
答案 0 :(得分:1)
问题:
您正在更改集合CIs
,但不通知它已更改。 ObservableCollections报告他们的更改,但是您将其覆盖,它将不会报告。
选项1:
由于使用了ObservableCollection
,因此可以将其直接添加到绑定集合中,它将自动通知UI。
因此,代替:
cis.Add(new CI { NodeName = Node.name, NodeStatus = Node.status });
执行以下操作:
CIs.Add(new CI { NodeName = Node.name, NodeStatus = Node.status });
如果执行此操作,则必须首先初始化CIs
:
public ObservableCollection<CI> CIs
{
get;
set;
} = new ObservableCollection<CI>(); // < initialize it
选项2:
将INotifyPropertyChanged接口添加到Nodes类并像这样通知:
this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( nameof( this.CIs ) ) );
在CIs
的二传手中