我不清楚什么与谁联系以及如何联系,所以让我告诉你我会怎么做。
ODP 构造了一个 clsPatients 的实例,其中包含一个填充有“数据”的“集合”。
public class clsPatients, INotifyPropertyChanged
{
public IBindingList Data {get;private set;}
private DispatcherTimer _timer;
public ClsPatients()
{
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromMilliseconds(someInterval);
_timer.Tick += DispatcherTimerTick;
_timer.Start();
}
/* etc etc */
}
clsPatients 还有一个 DispatcherTimer,它会定期更新 Data 属性并触发 PropertyChanged
public void DispatcherTimerTick(object sender, EventArgs e)
{
Data = new BindingList(Repository.GetMyDataLol());
// standard event firing method here, move along:
OnPropertyChanged("Data");
}
因此,在 UI 中,我将绑定这个集合(这可能没有错误,也可能没有):
<ItemsControl
ItemsSource="{Binding Data Source={StaticResource WaitingPatientDS}}">
<ItemsControl.Resources>
<DataTemplate>
<!-- yadda -->
更新数据时如何更新 UI:
- clsPatient 由 ObjectDataProvider 提供给 ItemsControl
- ItemsControl 使用 WPF 绑定基础结构来绑定 ODP 提供的实例的 Data 属性。
- clsPatient 的 DispatcherTimer(在 UI 线程上运行)更新 Data 并触发 PropertyChanged,它通知所有订阅此事件的绑定该属性已发生足够讽刺的变化
- 绑定接管并刷新 ItemsControl
要显示指示正在加载的动画,请向 clsPatient 添加另一个名为 Loading 的属性:
public Visibility Loading{get;private set}
并更新计时器滴答事件:
public void DispatcherTimerTick(object sender, EventArgs e)
{
Loading = Visibility.Visible;
OnPropertyChanged("Loading");
Data = new BindingList(Repository.GetMyDataLol());
OnPropertyChanged("Data");
Loading = Visibility.Hidden;
OnPropertyChanged("Loading");
}
然后,在 ui 中,将指标的 Visibility 属性绑定到 Loading:
<Grid DataContext="{Binding Data Source={StaticResource WaitingPatientDS}}">
<ItemsControl
ItemsSource="{Binding Data}">
<ItemsControl.Resources>
<DataTemplate>
<!-- yadda -->
</ItemsControl>
<Image Source="hurf.jpg" Visibility="{Binding Loading}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
当加载设置为可见时图像(或您要使用的任何其他控件)出现,并在其设置为隐藏时消失。因此,您可以在加载数据时显示图像。
如果 UI 没有更新,则该进程可能正在阻塞 UI,因为它在 UI 线程中执行。
要解决此问题,请运行 System.Threading.Timer 而不是 DispatcherTimer。STT 在 UI 以外的后台线程上运行。在计时器的回调方法中,使用调度程序更新 ui(Invoke 方法可能有问题;请查看 Dispatcher.Invoke 上的文档):
public void UpdateData(Object stateInfo)
{
var disp = Dispatcher.CurrentDispatcher();
Loading = Visibility.Visible;
disp.Invoke(() => { OnPropertyChanged("Loading");});
// optional sleep here
Data = new BindingList(Repository.GetMyDataLol());
disp.Invoke(() => { OnPropertyChanged("Data");});
Loading = Visibility.Hidden;
disp.Invoke(() => { OnPropertyChanged("Loading");});
}