0

我正在使用 ObjectDataProvider 调用一个带有 IObservableCollection 的类:

<ObjectDataProvider x:Key="WaitingPatientDS" 
      ObjectType="{x:Type local:clsPatients}">
      <ObjectDataProvider.ConstructorParameters>
          <sys:Boolean>True</sys:Boolean>
      </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

clsPatient 抓取数据并填充集合。它还使用计时器来轮询间隔时间重新查询数据库。

问题:如何在 clsPatient 中为 StartPoll 和 EndPoll 创建一个事件,更重要的是,如何将这些事件冒泡到我的 WPF 窗口的代码隐藏中?

4

1 回答 1

0

我不清楚什么与谁联系以及如何联系,所以让我告诉你我会怎么做。

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:

  1. clsPatient 由 ObjectDataProvider 提供给 ItemsControl
  2. ItemsControl 使用 WPF 绑定基础结构来绑定 ODP 提供的实例的 Data 属性。
  3. clsPatient 的 DispatcherTimer(在 UI 线程上运行)更新 Data 并触发 PropertyChanged,它通知所有订阅此事件的绑定该属性已发生足够讽刺的变化
  4. 绑定接管并刷新 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");});
}
于 2009-08-04T15:59:48.023 回答