2010-09-29 28 views
3

我有一個綁定到對象列表的WPF列表視圖。其中一個要顯示的項目是計算屬性(只讀,返回一個字符串),需要花費很少的時間進行計算。最初加載窗口時(或任何時候使用Notify事件更新UI),UI將在此數據綁定發生時掛起。我想知道的是一個很好的機制來處理這個問題(理想情況下,我希望按照使用微調框和文本「正在處理...」或類似文字)使屏幕變灰的方式進行操作。如何在WPF ListView處於DataBound狀態時顯示進度微調器(或其他用戶界面)?

我以爲我可以通過捕獲數據綁定事件的開始併發布故事(或類似事件)並在數據綁定事件結束時停止故事來做到這一點,但我無法找到那種性質的事件。

是否有推薦的機制來處理長數據綁定或我正在查找的事件是否存在,但是我正在尋找錯誤的位置?任何幫助,將不勝感激。

編輯:我能得到一個旋轉圖標(Cursor.Wait),而數據源和數據綁定(使用下面的解決方案的一部分),但是現在需要知道數據綁定完成時。 .Loaded事件似乎在控件放在屏幕上時立即觸發(這會立即發生),但在數據更新時不會發生。有沒有一個ListView的OnDataBoundCompleted類型事件,有關如何在數據綁定過程完成時得到通知的想法/想法?

編輯:現在看看TargetUpdated事件,但得到一些奇怪的結果。如果我在TargetUpdated的事件處理程序中放置消息框,則會更新UI(ListView顯示數據),然後顯示消息框。如果我刪除了消息框並只是有一個變量設置(即IsBusyCursor = Cursors.Arrow),它會在ListView顯示數據之前執行此操作。

**解決方案:**我最終創建了一個新的演示文稿對象並設置了Cursor = Wait,然後循環遍歷之前綁定到ListView的對象並創建演示文稿對象(這導致要執行的計算屬性),那麼一旦創建了展示對象列表,就將這些列表綁定到了ListView,並且使用Cursor = Arrow。令人失望的是,似乎並未出現DataBinding Completed類型事件(或者在數據綁定完成後觸發任何事件以更新UI可用),但此解決方案似乎可行。

回答

0

我最終創建了一個新的演示文稿對象並設置了Cursor =等待,然後循環通過先前綁定到ListView的對象並創建演示文稿對象(這導致要執行的計算屬性),然後一次演示文稿對象創建綁定到ListView和斯特光標=箭頭。

這裏似乎沒有DataBinding Completed類型的事件(或者一旦數據綁定完成後會觸發更新UI的任何事件),但此解決方案似乎可行。

1

看一看current thread,我在那裏解釋一個基本的BackgroundWorker,看看能否給你足夠的信息。

本質上,您將有一個顯示「Please Wait」控件的函數,然後使用BackgroundWorker在另一個線程上執行長時間運行計算。計算完成後,另一個事件觸發說BackgroundWorker已完成,然後您可以隱藏「請稍候」控件並綁定數據。或者,您可以在計算中報告進度,如果可能的話。

+0

這將工作得很好,如果它是一個長時間運行的計算,我正在調用(或類似),但因爲它被埋在一個屬性列表中的對象列表中,我沒有能夠以這種方式分離出來。 – ChrisHDog 2010-09-29 22:51:00

+0

這聽起來像是應該在單獨的線程上完成計算,而不僅僅是在數據綁定時間。否則,您將在計算執行時鎖定UI。過去我成功做到這一點的一種方法是使用擴展方法進行計算,在單獨的線程上調用。這是一個相當複雜的過程,爲此BackgroundWorker是一個簡化(在適合設計的情況下)。 – 2010-09-30 13:33:36

5

我有一個類似的情況ChrisHDog。我使用MVVM,這是我做的:

首先,在我的視圖模型,我設立財產稱爲IsBusy:

public bool IsBusy 
{ 
    get { return _isBusy; } 
    set 
    { 
     _isBusy = value; 
     NotifyPropertyChanged("IsBusy"); 
    } 
} 

然後,當它涉及到裝載的實際數據,我火了一個異步事件。但是在我這樣做之前,我將IsBusy屬性設置爲true。在我的XAML中,我將光標綁定到這一點:

<UserControl x:Class="UserControls.Views.AgentListView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:Converters="clr-namespace:UserControls.Utility.Converters" 
      xmlns:Controls="clr-namespace:UserControls.Controls" 
      xmlns:DependencyProperties="clr-namespace:UserControls.DependencyProperties" 
      Cursor="{Binding IsBusy, Converter={Converters:CursorExtensionConverter}}" > 

的CursorExtensionConverter只是一個簡單的IValueConverter到布爾轉換成可以被XAML理解正確的光標值:

namespace UserControls.Utility.Converters 
{ 
    public class CursorExtensionConverter : MarkupExtension, IValueConverter 
    { 
    private static CursorExtensionConverter instance = new CursorExtensionConverter(); 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value != null && ((bool) value)) 
     return Cursors.Wait; 
     else 
     return Cursors.Arrow; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return instance; 
    } 

    } 
} 

當數據完成異步獲取時,我將其編組回到UI線程,然後將IsBusy屬性設置爲false。光標然後恢復正常。

至於異步調用和編組回到用戶界面,我留給你看,因爲它是這個答案的不同部分。我使用Action委託並使用BeginInvoke將其稱爲異步,然後使用我在此處找到的技術將其恢復到UI線程:http://www.wintellect.com/CS/blogs/jlikness/archive/2009/12/16/dispatching-in-silverlight.aspx

我希望有幫助!

+0

好主意(我沒有意識到遊標設置),但我不是一個可以調用的長時間運行的進程,它是一個對象列表的屬性(所以在數據綁定發生),所以我希望使用「開始數據綁定」或「結束數據綁定」事件(並且我可以設置您的isBusy項目)。 – ChrisHDog 2010-09-29 22:53:26

+0

我試圖把數據源(和通知屬性)分配到一個單獨的線程,但會發生什麼情況是:光標忙,調用線程分配/通知,線程結束,光標不忙,幾秒鐘過去,那麼數據綁定就完成了。所以無論是需要另一個選項還是一種方法來確定數據綁定何時完成並在此時更新isBusy。想法? – ChrisHDog 2010-09-30 00:05:06

+1

所以看起來實際上需要時間的是綁定本身,數據到網格的綁定,而不是抓取。爲此我不確定該做什麼;我還沒有看到有關DataGrid的任何事件。我想知道是否在更新DataSource(我假設的ObservableCollection)之前和之後立即在ViewModel上設置IsBusy屬性會起作用? – 2010-10-01 12:28:13

相關問題