[英]ItemsControl - Bindable Collection - Ui update by Timer Event
I am creating up a dashboard type UI for couple of sensors device that are on the field. 我正在为现场的几个传感器设备创建一个仪表板类型的UI。 A timer based event gets the last record from the DB and updates the dashboard UI. 基于计时器的事件从数据库获取最后一条记录,并更新仪表板UI。 I want to dynamically creating my "sensors" which are on BindableCollection and then associated with a ItemsControl on the XAML that contains nested ItemsControl. 我想动态创建我的“传感器”,它们位于BindableCollection上,然后与包含嵌套ItemsControl的XAML上的ItemsControl关联。 Using MVVM architecture, and Caliburn Micro for Binding. 使用MVVM体系结构和Caliburn Micro进行绑定。
Have used full property and make sure I call NotifyOfPropertyChange after updating my BindableColleciton 已使用完整属性,并确保在更新我的BindableColleciton之后我调用NotifyOfPropertyChange
Edit: Following others threads I have change the System.Timer for a DispatcherTimer() so the update runs on the UI thread. 编辑:在其他线程之后,我为DispatcherTimer()更改了System.Timer,以便更新在UI线程上运行。 DispatcherTimer vs a regular Timer in WPF app for a task scheduler WPF应用程序中的DispatcherTimer与常规Timer的比较
Moreover, because my BindableCollection members were always the same I have make sure the collection is recreated at every, as I have the idea "An ObservableCollection will notify the UI when a record is added or removed but not when a record is edited. It's up to the object that has been changed to notify that it has changed." 此外,由于我的BindableCollection成员始终相同,因此我确保每次都重新创建该集合,因为我的想法是“一个ObservableCollection会在添加或删除记录时通知UI,但在编辑记录时不会通知UI。到已更改的对象,以通知它已更改。”
Properties: 属性:
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: 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>
Event (Edited): 活动(已编辑):
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");
}
This is the first view / view model of my application, the UI refresh event as above always work until I have focus a different view and return to it. 这是我的应用程序的第一个视图/视图模型,上面的UI刷新事件始终有效,直到我关注另一个视图并返回它为止。 The timer is def still being triggered and placing the right state on the BindableCollection. 定时器仍在定义中,并将正确的状态放在BindableCollection上。 Also, even the properties that simple Int do not update. 同样,即使是简单的Int的属性也不会更新。 Putting a break point a the property setter I can see it never hits its like NotifyOfPropertyChange event is not triggered. 将断点放在属性设置器上,我可以看到它从未命中,就像未触发NotifyOfPropertyChange事件一样。 Any idea? 任何想法?
Thanks everyone for the tips and help. 感谢大家的提示和帮助。
I have made it work, there was a couple of things that were causing the UI not be refreshed. 我已经使它工作了,有几件事导致UI无法刷新。
It was a combination of all the 3 points above. 这是以上所有三点的结合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.