0

我有一个绑定到属性的列表。还有一个加载事件“ListLoaded”。

<ListView ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" BorderThickness="0" HorizontalAlignment="Left" ItemsSource="{Binding DoctorDetailsBooking,Mode=TwoWay}">
    <i:Interaction.Triggers>
         <i:EventTrigger EventName="Loaded">
             <cmd:EventToCommand Command="{Binding ListLoaded}" PassEventArgsToCommand="True" />
          </i:EventTrigger>
    </i:Interaction.Triggers>

在其加载事件中,我将第一个选定项目设置为 true 并更改该项目的背景颜色。

一些操作和 API 调用是在 ViewModel 的构造函数中进行的。load 事件也在构造函数中设置。加载屏幕需要一些时间。所以我在任务工厂的构造函数中添加了整个代码,并相应地设置了进度条的可见性。

Task tskOpen = Task.Factory.StartNew(() =>
            {
                ProgressBarVisibility = Visibility.Visible;

                DataAccess data = new DataAccess();
                DoctorDetailsBooking = data.GetDoctorsList(Convert.ToDateTime(BookingDate).Date);
                FillSlots();
                **ListLoaded = new RelayCommand<RoutedEventArgs>(ListViewLoaded);**

            }).ContinueWith(t =>
                {
                    ProgressBarVisibility = Visibility.Hidden;
                }, TaskScheduler.FromCurrentSynchronizationContext());    

问题是,当我在任务中提供代码时,ListeViewLoaded 事件不会触发。因此,列表视图未正确加载。如果我删除代码的任务部分,则触发事件并且一切正常。

我不太了解线程和任务概念。我在这里错过了什么吗?

4

1 回答 1

1

如果我理解正确,您将面临延迟事件处理——即不是立即处理事件,而是在满足某些条件后处理事件。我要做的是将触发事件的参数存储在集合中,然后在满足条件后调用处理程序。在您的情况下,它将类似于以下内容:

//create a queue to store event args
var deferredEventArgs = new Queue<RoutedEventArgs>();
//temporarily assign a handler/command that will store the args in the queue
ListLoaded = new RelayCommand<RoutedEventArgs>(e => deferredEventArgs.Enqueue(e));

Task tskOpen = Task.Factory.StartNew(() =>
{
    ProgressBarVisibility = Visibility.Visible;
    DataAccess data = new DataAccess();
    DoctorDetailsBooking = data.GetDoctorsList(Convert.ToDateTime(BookingDate).Date);
    FillSlots();

    //assign the proper handler/command once its ready
    ListLoaded = new RelayCommand<RoutedEventArgs>(ListViewLoaded);

}).ContinueWith(t =>
{
    //"flush" the queue - handle previous events
    //decide whether it should be done on the UI thread
    while(deferredEventArgs.Any())
        ListViewLoaded(deferredEventArgs.Dequeue());
    ProgressBarVisibility = Visibility.Hidden;
}, TaskScheduler.FromCurrentSynchronizationContext());

您可能需要考虑是要处理所有发生的事件还是只处理最后一个事件,在这种情况下,单个变量就足够了,而不是队列。

于 2015-02-04T10:06:55.737 回答