2012-01-03 22 views
8

मेरे पास एक wpf एप्लिकेशन है जो बहुत भारी क्रिया करता है जिसमें उपयोगकर्ता को "सोचता है" के दौरान प्रतीक्षा करने की आवश्यकता होती है।"व्यस्त" प्रभाव ओवरले

मैं क्या करना चाहता हूं, जबकि एप्लिकेशन का मुख्य धागा सोच रहा है, एक और धागा पूरी खिड़की को अक्षम कर देगा और इसे एक भूरे रंग का रंग देगा और स्क्रीन के बीच में एक गोलाकार प्रगति पट्टी दिखाई देगी।

यह एक बड़ा सवाल है और मुझे केवल सामान्य विचार करने के लिए पूरे कोड की आवश्यकता नहीं है।

अपने सभी मदद के लिए धन्यवाद ..

उत्तर

2

एक नया धागा करने के लिए भारी कार्रवाई बोझ उतार लेना और मुख्य थ्रेड पर यूआई सामान (अक्षम करते हैं, बाहर ग्रे और प्रगति बार) से करते हैं। BackgroundWorker and Dispatcher देखें।

यूआई सामान के लिए एक नया धागा का उपयोग करना संभव है, लेकिन मौजूदा विंडो का उपयोग नहीं कर रहा है। एक यूआई कंट्रोल (डिस्पैचर) ऑनलाइन इस्तेमाल किया जा सकता है जिसे थ्रेड द्वारा इस्तेमाल किया जाता है। हालांकि आप यूआई सामान करने के लिए एक नया थ्रेड बना सकते हैं और नए डिस्पैचर के साथ एक नई विंडो का उपयोग कर सकते हैं। इसके बाद आपको मूल पर नई विंडो को स्थान देना होगा। मेरे पहले सुझाव के रूप में आसान नहीं है। यदि आप नहीं जानते कि भारी कार्रवाई कब की जाती है तो यह एक विकल्प हो सकता है। here, here और here देखें।

+0

बहुत बहुत धन्यवाद, यह बेहद सहायक था! –

3

उपयोग Dispatcher.BeginInvoke UI घटक और इस शो के सक्षम करें-संपत्ति को बदलने के लिए/आप BackgroundWorker-Class

+0

बहुत बहुत धन्यवाद, यह बेहद सहायक था! –

2

उपयोग कर सकते हैं इस पर एक नजर डालें कार्यकर्ता धागा

कार्यकर्ता थ्रेड के लिए से बाहर प्रगतिबार छिपाने नमूना:

public void DoHeavyWork() 
    { 
     mainDispatcher = Dispatcher.CurrentDispatcher; 
     DisableWindow(); 
     workDelegate.BeginInvoke(EnableWindowCallBack, null); 
    } 

    private void EnableWindowCallBack(IAsyncResult asyncResult) 
    { 
     workDelegate.EndInvoke(asyncResult); 
     mainDispatcher.InvokeIfRequired(() => { EnableWindow(); }); 
    } 

जब आप फोन DoHeavyWork मैं मान हम धागा यूआई, जो हमेशा की तरह होना चाहिए की पहुंच न हो पर हैं। DisableWindow एनीमेशन दिखाता है या जो भी काम करते समय दिखाया जाना चाहिए। फिर आप अपने पूर्वनिर्धारित प्रतिनिधि, workDelegate का आह्वान करते हैं जो एक नए धागे पर चलेंगे, और जब यह हो जाएगा, तो कॉलबैक को दृश्य को पुनर्स्थापित करना चाहिए।

ध्यान दें कि EnableWindow पर कॉल को उस थ्रेड पर बनाया जाना चाहिए जिसकी यूआई तक पहुंच हो।

+0

बहुत बहुत धन्यवाद, यह बेहद सहायक था! –

+0

मदद की खुशी है। आप वोटिंग के द्वारा अपना धन्यवाद दिखा सकते हैं और जवाबों में से एक को सही उत्तर के रूप में स्वीकार कर सकते हैं। –

12

उपर्युक्त सुझावों (पृष्ठभूमि कार्यकर्ता, डिस्पैचर) के अतिरिक्त - हाँ, आप जो चाहते हैं उसे पाने के लिए ये सही तकनीक हैं, लेकिन मुझे आपके प्रश्न में आपके द्वारा अनुरोधित यूआई प्रभाव पर चर्चा करने दें। यदि आप एमवीवीएम पैटर्न का उपयोग कर रहे हैं, तो आप कुछ "मैं व्यस्त हूं" यूआई बना सकता हूं और यूआई को दिखाने और छिपाने के लिए दृश्य मॉडल में एक आईसबीसी संपत्ति से जुड़ सकता हूं। उदाहरण के लिए:

public class MyViewModel : INotifyPropertyChanged 
{ 
    // Bind to this property any UI you want to 
    // show/hide during long running updates 
    public bool IsBusy 
    { 
     get { return _isBusy; } 
     set 
     { 
      _isBusy = true; 
      OnPropertyChanged("IsBusy"); 
     } 
    } 

    private void OnPropertyChanged(string prop) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(prop)); 
     } 
    } 

    // Note: This is intended to be called on a background thread 
    private void DoLongRunningOperationOnABackgroundThread() 
    { 
     try 
     { 
      IsBusy = true; 

      // do your work 
     } 
     finally 
     { 
      IsBusy = false; 
     } 
    } 
} 

फिर यूआई प्रयोग में यह XAML (या इसी तरह)

<UserControl:MyControl x:Class="MyApp.MyControl" 
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <UserControl.Resources> 
     <BooleanToVisibilityConverter x:Key="boolToVis"/> 
    </UserControl.Resources> 
    <Grid> 
     <!-- your UI code goes here --> 

     <!-- Below this, at higher Z-Order place a control to gray out the screen when IsBusy = true --> 
     <Border Background="#55000000" BorderThickness="0" Visibility="{Binding IsBusy, Converter={StaticResource boolToVis}}"> 
      <TextBlock Text="I AM BUSY!" Font-Size="32" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/> 
     </Border> 
    <Grid> 
</UserControl>  

शुद्ध प्रभाव है जब आप अपने viewmodel में DoLongRunningOperation समारोह कॉल करने के लिए एक पृष्ठभूमि के कार्यकर्ता या ThreadPool का उपयोग किया जाएगा, Xaml में परिभाषित सीमा ऑपरेशन शुरू होने/बंद होने के रूप में दिखाएगी/छुपाएगी। आपको यहां आने के लिए प्रेषक की आवश्यकता नहीं होगी क्योंकि WPF आपके लिए थ्रेड मार्शलिंग को संभालता है।

यूआई को मसाला करने के लिए नेट पर whirlygig एनिमेशन आदि के साथ व्यस्त नियंत्रण के कार्यान्वयन भी हैं।

सर्वश्रेष्ठ संबंध,

+0

धन्यवाद, मुझे कुछ शांत एनिमेशन कार्यान्वयन ऑनलाइन मिले हैं बहुत धन्यवाद –

+0

कोई जांच नहीं :) बस ध्यान दें कि आप सीधे किसी अन्य नियंत्रण (जेड-इंडेक्स में उच्च) पर नियंत्रण रखने के लिए WPF ग्रिड का उपयोग कर सकते हैं। यह ग्रे-आउट प्रभाव के लिए बहुत उपयोगी है जिसे आप ढूंढ रहे हैं। –

संबंधित मुद्दे