我正在为现场的几个传感器设备创建一个仪表板类型的UI。基于计时器的事件从数据库获取最后一条记录,并更新仪表板UI。我想动态创建我的“传感器”,它们位于BindableCollection上,然后与包含嵌套ItemsControl的XAML上的ItemsControl关联。 使用MVVM架构和Caliburn Micro进行绑定。
使用了完整属性,并确保在更新BindableColleciton之后我调用NotifyOfPropertyChange
编辑:在其他线程之后,我将System.Timer更改为DispatcherTimer(),以便更新在UI线程上运行。 DispatcherTimer vs a regular Timer in WPF app for a task scheduler
此外,由于我的BindableCollection成员始终相同,因此我确保每次都重新创建该集合,因为我有一个想法:“在添加或删除记录时,ObservableCollection会通知UI,而在编辑记录时,它不会通知UI。 。由已更改的对象来通知它已更改。”
属性:
private int _offlineSensors;
public int OfflineSensors
{
get { return _offlineSensors; }
set
{
_offlineSensors = value;
NotifyOfPropertyChange(() => OfflineSensors);
}
}
private int _latchedAlarms;
public int LatchedAlarms
{
get { return _latchedAlarms; }
set
{
_latchedAlarms = value;
NotifyOfPropertyChange(() => LatchedAlarms);
}
}
private int _activeAlarms;
public int ActiveAlarms
{
get { return _activeAlarms; }
set
{
_activeAlarms = value;
NotifyOfPropertyChange(() => ActiveAlarms);
}
}
private Caliburn.Micro.BindableCollection<SensorStatusTable> _sensorStatusFilteredDash;
public Caliburn.Micro.BindableCollection<SensorStatusTable> SensorStatusFilteredDash
{
get { return _sensorStatusFilteredDash; }
set
{
_sensorStatusFilteredDash = value;
NotifyOfPropertyChange(() => SensorStatusFilteredDash);
}
}
XAML:
<ItemsControl Foreground="Black" Background="Black" ItemsSource="{Binding Path=SensorStatusFilteredDash, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="RoyalBlue" BorderThickness="2" Margin="2" Padding="5">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" FontSize="20" />
<Image MaxWidth="60" MaxHeight="60" Source="{Binding CardStatusImage, Converter={StaticResource ResourceKey = ImageConverter}, UpdateSourceTrigger=PropertyChanged}" Stretch="Uniform"></Image>
<ItemsControl Foreground="Black" Background="Black" ItemsSource="{Binding Path=SensorTypes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }" TextWrapping="WrapWithOverflow" FontWeight="Bold" FontSize="12" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Margin="25.5,1,18,1"></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl Foreground="Black" Background="Black" ItemsSource="{Binding Path=InternalSensorStatusImages, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Margin="11.5,1" MaxWidth="40" HorizontalAlignment="Center" VerticalAlignment="Center" MaxHeight="40" Source="{Binding Converter={StaticResource ResourceKey = ImageConverter}}" Stretch="Uniform"></Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl Foreground="Black" Background="Black" ItemsSource="{Binding Path=InternalSensorStatusDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" TextWrapping="WrapWithOverflow" FontWeight="Bold" FontSize="12" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Margin="10,1,10,1"></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
事件(已编辑):
var conn = GlobalConfig.Connections.FirstOrDefault(c => c.GetType() == typeof(SQLConnector));
if (conn == null) return;
try
{
ActiveAlarms = conn.GetNumberActiveAlarms(0);
LatchedAlarms = conn.GetNumberActiveAlarms(2);
GasSensors = new Caliburn.Micro.BindableCollection<GasSensor>(conn.GetGasSensors());
SensorStatusDash = new Caliburn.Micro.BindableCollection<SensorStatusTable>(conn.SensorStatusDashboard());
_sensorStatusFilteredDash.Clear();
_sensorStatusFilteredDash = new Caliburn.Micro.BindableCollection<SensorStatusTable>(StatusImageConverter());
NotifyOfPropertyChange(() => SensorStatusFilteredDash);
NotifyOfPropertyChange(() => OfflineSensors);
NotifyOfPropertyChange(() => ActiveAlarms);
NotifyOfPropertyChange(() => LatchedAlarms);
}
catch (Exception ex)
{
_logger.Error(ex, "Error - Refreshing Dashboard Status");
}
这是我的应用程序的第一个视图/视图模型,上面的UI刷新事件始终有效,直到我将焦点放在另一个视图上并返回为止。定时器仍在定义中,并将正确的状态放在BindableCollection上。同样,即使是简单的Int的属性也不会更新。将断点放在属性设置器上,我可以看到它从未命中,就像未触发NotifyOfPropertyChange事件一样。有什么想法吗?
答案 0 :(得分:0)
感谢大家的提示和帮助。
我已经使它工作了,有一些原因导致UI无法刷新。
这是以上所有三点的结合。