2011-09-08 11 views
28

मेरे पास एमवीवीएम पैटर्न का उपयोग करके एक WPF एप्लिकेशन है जिसे कभी-कभी प्रतीक्षाकर्ता को दिखाना पड़ता है जब उपयोगकर्ता को प्रतीक्षा करने में व्यस्त होता है। इस पृष्ठ पर उत्तरों के संयोजन के लिए धन्यवाद: display Hourglass when application is busy, मेरे पास एक समाधान है जो लगभग काम करता है (हालांकि यह वास्तव में भावना में एमवीवीएम नहीं है)। मैं यह कर जब भी मैं कुछ मेरी ViewModels में समय लेने वाली कार्य करें:डब्ल्यूपीएफ एप्लिकेशन व्यस्त होने पर डब्ल्यूटीएफ एप्लीकेशन व्यस्त होने पर प्रतीक्षाकर्ता कैसे दिखाएं

using (UiServices.ShowWaitCursor()) 
{ 
.. do time-consuming logic 
this.SomeData = somedata; 
} 

(ShowWaitCursor() की ओर से एक IDisposable कि waitcursor से पता चलता है जब तक यह का निपटारा किया जा रहा है) मेरे उदाहरण में अंतिम पंक्ति जहां है मैं कुछ संपत्ति सेट करें। यह संपत्ति मेरे एक्सएएमएल में बनी हुई है, उदा। इस तरह:

<ItemsControl ItemsSource="{Binding SomeData}" /> 

हालांकि, इस के बाद से वस्तुओं की एक लंबी सूची है और जटिल datatemplates साथ कभी कभी, आदि वास्तविक बाध्यकारी हो सकता है और कुछ समय प्रतिपादन समय की एक पर्याप्त राशि लेता है। चूंकि यह बाध्यकारी मेरे उपयोग कथन के बाहर जगह लेता है क्योंकि उपयोगकर्ता के लिए वास्तविक प्रतीक्षा खत्म हो जाने से पहले प्रतीक्षाकर्ता दूर चलेगा।

तो मेरा सवाल यह है कि एक डब्ल्यूपीएफ एमवीवीएम एप्लिकेशन में प्रतीक्षाकर्ता कैसे करें जो डेटाबेस में डाटाबेसिंग लेता है?

उत्तर

82

इस्क का जवाब मेरे लिए काम नहीं करता है, क्योंकि उपयोगकर्ता के लिए वास्तविक प्रतीक्षा खत्म होने पर यह कार्य करने की समस्या का समाधान नहीं करता है। मैंने ऐसा करने का अंत किया: हर बार जब मैं कुछ समय-समय पर काम करना शुरू करता हूं, तो मैं एक सहायक विधि कहता हूं। यह सहायक विधि कर्सर को बदलती है और उसके बाद एक डिस्पैचर टिमर बनाता है जिसे एप्लिकेशन निष्क्रिय होने पर बुलाया जाएगा। जब यह कहा जाता है यह mousecursor वापस सेट:

/// <summary> 
/// Contains helper methods for UI, so far just one for showing a waitcursor 
/// </summary> 
public static class UiServices 
{ 

    /// <summary> 
    /// A value indicating whether the UI is currently busy 
    /// </summary> 
    private static bool IsBusy; 

    /// <summary> 
    /// Sets the busystate as busy. 
    /// </summary> 
    public static void SetBusyState() 
    { 
      SetBusyState(true); 
    } 

    /// <summary> 
    /// Sets the busystate to busy or not busy. 
    /// </summary> 
    /// <param name="busy">if set to <c>true</c> the application is now busy.</param> 
    private static void SetBusyState(bool busy) 
    { 
      if (busy != IsBusy) 
      { 
       IsBusy = busy; 
       Mouse.OverrideCursor = busy ? Cursors.Wait : null; 

       if (IsBusy) 
       { 
        new DispatcherTimer(TimeSpan.FromSeconds(0), DispatcherPriority.ApplicationIdle, dispatcherTimer_Tick, Application.Current.Dispatcher); 
       } 
      } 
    } 

    /// <summary> 
    /// Handles the Tick event of the dispatcherTimer control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
    private static void dispatcherTimer_Tick(object sender, EventArgs e) 
    { 
      var dispatcherTimer = sender as DispatcherTimer; 
      if (dispatcherTimer != null) 
      { 
       SetBusyState(false); 
       dispatcherTimer.Stop(); 
      } 
    } 
} 
+0

महान कार्यान्वयन:

यहाँ मेरी हल है! यह मेरे लिए सही काम करता है जब किसी तीसरे पक्ष के यूआई बाइंडिंग ऑपरेशन में समय खपत हो रही है; जब मुझे वास्तव में पता नहीं होता कि यह कब किया जाता है। धन्यवाद! –

+0

मैं इसे एक बूल के बजाय गिनती का उपयोग करने के लिए बदल दूंगा। इस तरह, कई जगहें कह सकती हैं कि उन्हें प्रतीक्षा कर्सर की आवश्यकता है और यह तब तक रहेगा जब तक कि वे इसे छोड़ नहीं देते। –

+1

अच्छा! धन्यवाद! – Dummy01

6

मैंने अतीत में जो किया है वह व्यूमोडेल में बूलियन गुणों को परिभाषित करना है जो इंगित करता है कि लंबी गणना प्रगति पर है। उदाहरण के लिए IsBusy जो निष्क्रिय होने पर काम करने और झूठी होने पर सत्य पर सेट है।

फिर दृश्य में मैं इस से जुड़ता हूं और प्रगति पट्टी या स्पिनर या इसी तरह प्रदर्शित करता हूं, जबकि यह संपत्ति सत्य है। मैंने व्यक्तिगत रूप से कभी भी इस दृष्टिकोण का उपयोग कर कर्सर सेट नहीं किया है, लेकिन मुझे नहीं लगता कि यह क्यों संभव नहीं होगा।

यदि आप और भी नियंत्रण चाहते हैं और एक साधारण बूलियन पर्याप्त नहीं है, तो आप VisualStateManager का उपयोग कर सकते हैं जिसे आप अपने व्यूमोडेल से ड्राइव करते हैं। इस दृष्टिकोण के साथ आप विस्तार से बता सकते हैं कि यूआई को व्यूमोडेल की स्थिति के आधार पर कैसे देखना चाहिए।

1

इसके अलावा इसाक Savo के योगदान के लिए, आप एक काम के लिए नमूना Brian Keating's blog पर एक नजर है सकते हैं।

7

इसलिए मुझे ओवरराइड कर्सर का उपयोग करना पसंद नहीं आया क्योंकि मेरे पास कई खिड़कियां थीं और मैं उन लोगों को चाहता था जो वर्तमान में सामान्य तीर कर्सर रखने के लिए कुछ निष्पादित नहीं कर रहे थे।

<Window.Style> 
    <Style TargetType="Window"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding IsBusy}" Value="True"> 
       <Setter Property="Cursor" Value="Wait" /> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</Window.Style> 
<Grid> 
    <Grid.Style> 
     <Style TargetType="Grid"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding IsBusy}" Value="True"> 
        <Setter Property="IsHitTestVisible" Value="False" /> <!-- Ensures wait cursor is active everywhere in the window --> 
        <Setter Property="IsEnabled" Value="False" /> <!-- Makes everything appear disabled --> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Grid.Style> 
    <!-- Window controls go here --> 
</Grid> 
संबंधित मुद्दे