关于 c#:MVVM WPF ViewModel DispatcherTimer 不更新视图?

MVVM WPF ViewModel DispatcherTimer not updating view?

我的 ViewModel 中有一个 DispatcherTimer,我可以看到每个间隔都在触发,但是视图没有更新?

提要数据来自 xml url,我试图每 x 秒刷新一次表单。也许或多或少的标签/不同的状态

这里是代码片段:

ViewModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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();

}

模型.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<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>

在没有启用/注释掉计时器的情况下表单的外观:

enter

启用计时器代码后,网格不会添加任何内容:

enter

1
cis.Add(new CI { NodeName = Node.name, NodeStatus = Node.status });

这样做:

1
cis.Add(new CI { NodeName = Node.name, NodeStatus = Node.status });

如果你这样做你必须先初始化CIs

1
2
3
4
5
public ObservableCollection<CI> CIs
{
    get;
    set;
} = new ObservableCollection<CI>(); // < initialize it

选项 2:

将 INotifyPropertyChanged 接口添加到 Nodes 类并通知如下:

this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( nameof( this.CIs ) ) );

CIs

的setter中