2009-07-10 9 views
26

मुझे एक ही प्रक्रिया से दो (या अधिक) WPF विंडो बनाने की आवश्यकता है। लेकिन खिड़कियों को अलग धागे से संभाला जाना चाहिए क्योंकि वे एक-दूसरे को अवरुद्ध नहीं कर पाएंगे। मैं यह कैसे करु?मैं विभिन्न धागे पर WPF विंडो कैसे बना और दिखा सकता हूं?

WinForms इसमें द्वारा हासिल की है:

  • प्रारंभ एक नया धागा
  • नया थ्रेड
  • कॉल पैरामीटर के रूप में फार्म के साथ Application.Run से एक फ़ॉर्म बनाएं

लेकिन मैं डब्ल्यूपीएफ में ऐसा कैसे करूं?

उत्तर

40

msdn के रूप में कहता है:

private void NewWindowHandler(object sender, RoutedEventArgs e) 
{  
    Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint)); 
    newWindowThread.SetApartmentState(ApartmentState.STA); 
    newWindowThread.IsBackground = true; 
    newWindowThread.Start(); 
} 

private void ThreadStartingPoint() 
{ 
    Window1 tempWindow = new Window1(); 
    tempWindow.Show();  
    System.Windows.Threading.Dispatcher.Run(); 
} 

संपादित करें: यह कोई पुराना जवाब है, लेकिन जब से यह अक्सर दौरा किया जा रहा है, मैं भी निम्न संशोधन/सुधार (परीक्षण नहीं) के बारे में सोच सकता है।

आप इस तरह के एक विंडो को बंद करने के लिए, बस धागा (प्रतिनिधि) के बाहर से खिड़की ऑब्जेक्ट के संदर्भ रखने के लिए, और फिर उस पर करीब आह्वान, कुछ इस तरह करना चाहते हैं: यदि

void CloseWindowSafe(Window w) 
{ 
    if (w.Dispatcher.CheckAccess()) 
     w.Close(); 
    else 
     w.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(w.Close)); 
} 

// ... 
CloseWindowSafe(tempWindow); 

नया थ्रेड समाप्त हो सकता है टिप्पणी में (जबरन रोका गया), प्रश्न के साथ लाइन में:

private void ThreadStartingPoint() 
{ 
    try{ 
     Window1 tempWindow = new Window1(); 
     tempWindow.Show();  
     System.Windows.Threading.Dispatcher.Run(); 
    } 
    catch(ThreadAbortException) 
    { 
     tempWindow.Close(); 
     System.Windows.Threading.Dispatcher.InvokeShutdown(); 
    } 
    //the CLR will "rethrow" thread abort exception automatically 
} 

अस्वीकरण: सूत्र निरस्त किया जा रहा है (लगभग हमेशा) सर्वोत्तम प्रथाओं के खिलाफ घर में ऐसा नहीं करते हैं,। थ्रेड को किसी भी विभिन्न सिंक्रनाइज़ेशन तकनीकों के माध्यम से सुन्दर तरीके से संभाला जाना चाहिए, या इस मामले में, केवल window.Close()

+3

ग्रेट मैं इस तरह से –

+0

मैं जानता हूँ कि यह एक पुराने सवाल है बनाए गए एक विंडो को बंद कर सकते हैं लेकिन यह कैसे दृष्टिकोण अभी भी काम करता है। मेरे पास सिर्फ एक समस्या है - मैं इसे विंडो लोड करने के लिए उपयोग करता हूं - नए थ्रेड में लोडिंग विंडो दिखाएं -> सामान करें -> newThread.Abort() और यह ठीक है लेकिन अगर मैं इसे फिर से करूँगा तो यह पूरे ऐप को दुर्घटनाग्रस्त कर देगा। क्योंकि यह फिर से प्रेषक को चलाने जा रहा है। इसे कैसे हल करें? – MajkeloDev

+0

हाय, मैं भी इसके साथ संघर्ष कर रहा था। मेरे लिए, यह [लिंक] (https://dontpaniclabs.com/blog/post/2013/11/14/dynamic -स्प्लाश-स्क्रीन-इन-डब्ल्यूपीएफ /) काम किया। यह मैनुअल रीसेट इवेंट-वे का उपयोग करता है। डाउनलोड करने का एक स्रोत है और भी जांचें (गिटहब) – dba

2

के माध्यम से मुझे लगता है कि मुझे जवाब मिला है। इस question में जॉन स्कीट के जवाब को देखें। मैं वास्तव में क्या देख रहा था

private void ThreadStartingPoint() 
{ 
    Window1 tempWindow = new Window1(); 
    tempWindow.Show();  
    System.Windows.Threading.Dispatcher.Run(); 
} 
+0

ओउप्स .. देर से, धन्यवाद kek444। –

1

:

मूल रूप से आप अपने धागा शुरू विधि में इस तरह से करते हैं।

मैं इस हालांकि जैसे कि यह कर रहा हूँ:

App.xaml.cs

public partial class App : Application 
    { 
     protected override void OnStartup(StartupEventArgs e) 
     { 
      base.OnStartup(e); 

      Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint)); 
      newWindowThread.SetApartmentState(ApartmentState.STA); 
      newWindowThread.IsBackground = true; 
      newWindowThread.Start(); 

      var window = new MainWindow(newWindowThread); 
      window.DataContext = new MainWindowViewModel(window); 
      window.Show(); 
     } 

     private void ThreadStartingPoint() 
     { 
      SplashWindow tempWindow = new SplashWindow(); 
      tempWindow.Show(); 
      System.Windows.Threading.Dispatcher.Run(); 
     } 
    } 

MainWindow.Xaml.cs

public partial class MainWindow : Window 
{ 
    public MainWindow(Thread splashWindowThread) 
    { 
     InitializeComponent(); 

     MyInializaComponent(); 

     splashWindowThread.Abort(); 
    } 

//void DoStuff(){}; 
} 

मैं के बाद चले जाओ करने के लिए अपने स्प्लैश स्क्रीन की जरूरत कार्यक्रम ने सभी लोडिंग की है।

9

जो भी इसके लायक है, क्योंकि यह उत्तर Google द्वारा प्रदान किया गया पहला परिणाम है। कोई विशेष विंडो बंद करता नहीं इस विंडो का धागा डिस्पैचर समाप्त

"हमारे सरल समाधान के लिए एक पकड़ नहीं है, इसलिए धागा चलता रहे और बाद: मैं भी Eugene Prystupa's Weblog से लिया निम्नलिखित जोड़ना चाहते हैं। सभी खिड़कियों को बंद करना, प्रक्रिया समाप्त नहीं होगी और एक भूत प्रक्रिया बन जाएगी।[] सरल (और सही नहीं) समाधान हमारे थ्रेड को पृष्ठभूमि के रूप में चिह्नित करना है (थ्रेड का उपयोग करना। आईएस बैकग्राउंड = सत्य;)। यह मुख्य UI थ्रेड समाप्त होने पर उन्हें समाप्त करने के लिए मजबूर कर देगा।

उचित कार्यान्वयन अब इसकी आवश्यकता होने पर प्रेषक को चुपचाप बंद कर देगा। नीचे दिए गए कोड एक रणनीति डिस्पैचर को समाप्त करने का एक उदाहरण है जब खिड़की बंद कर देता:।? "

private void OnCreateNewWindow(object sender, RoutedEventArgs e) 
{ 
    Thread thread = new Thread(() => 
    { 
     Window1 w = new Window1(); 
     w.Show(); 

     w.Closed += (sender2, e2) => 
      w.Dispatcher.InvokeShutdown(); 

     System.Windows.Threading.Dispatcher.Run(); 
    }); 

    thread.SetApartmentState(ApartmentState.STA); 
    thread.Start(); 
} 
+1

उपर्युक्त कोई काम नहीं करता है, तो एक समान संदर्भ लिंक: [एक अलग थ्रेड में एक WPF विंडो लॉन्च करना, भाग 1] (http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in -एक-अलग धागा-भाग -1 /) –

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