2011-05-27 10 views
49

को बदलना WPF अपनी Main() विधि को परिभाषित करता है। मुझे इसे अपने Main विधि से बदलने के बारे में कैसे जाना चाहिए (सामान्यतः) WPF MainWindow (उदा। कमांड-लाइन तर्कों के माध्यम से एक गैर-WPF स्क्रिप्टिंग मोड जोड़ने के लिए) खोलता है?WPF एंट्री पॉइंट

उत्तर

48

कुछ उदाहरण Page को ApplicationDefinition से App.xaml एक्शन बिल्ड बदल रहा है और अपने स्वयं के Main() कि App वर्ग को दर्शाता है और उसके Run() प्रणाली को बुलाती है लेखन को दर्शाती है, लेकिन इस में कुछ अवांछित परिणाम का उत्पादन कर सकते App.xaml में एप्लिकेशन-व्यापी संसाधनों का समाधान।

इसके बजाय, मैं अपने ही वर्ग में अपने स्वयं के Main() करने का सुझाव और परियोजना संपत्तियों में उस वर्ग के लिए स्टार्टअप वस्तु की स्थापना:

public class EntryPoint { 
    [STAThread] 
    public static void Main(string[] args) { 
     if (args != null && args.Length > 0) { 
      // ... 
     } else { 
      var app = new App(); 
      app.InitializeComponent(); 
      app.Run(); 
     } 
    } 
} 

मैं इस कुछ AppDomain घटनाओं होना चाहिए का लाभ लेने के है किसी और चीज से पहले सदस्यता लें (जैसे AssemblyResolve)। App.xaml को Page पर सेट करने के अनचाहे परिणाम जो मैंने अनुभव किया है, मैंने UserControl व्यू (एम-वी-वीएम) डिज़ाइन-टाइम के दौरान App.xaml में आयोजित संसाधनों को हल नहीं किया है।

+0

ठीक है, मैं रन() के बजाय App.Main() को कॉल कर रहा हूं क्योंकि मुख्य() कॉल InitializeComponent(), जो स्टार्टअप ईवेंट हैंडलर स्थापित करता है। मुझे अनुमान है कि आपको रन() को कॉल करना होगा यदि आप पेज पर बिल्ड एक्शन बदलते हैं (चूंकि मुख्य() गायब हो जाता है) लेकिन मैंने इसे एप्लिकेशनडिफिनिशन के रूप में छोड़ दिया है। – Qwertie

+2

जेनरेट किया गया 'मुख्य()' बस 'ऐप' को तुरंत चालू करता है और 'रन() 'कॉल करता है। 'स्टार्टअप' ईवेंट 'System.Windows.Aplication' के कन्स्ट्रक्टर में निकाल दिया गया है। 'रन()' एक डिस्पैचर 'संलग्न करता है और संदेश पंप शुरू करता है। 'प्रारंभिक कॉम्पोनेंट()' को 'ऐप्स' के निर्माता में बुलाया जाना चाहिए। क्या ऐसा नहीं है? –

+0

नहीं, ऐप के लिए माइक्रोसॉफ्ट द्वारा जेनरेट किए गए कोड में एक कन्स्ट्रक्टर शामिल नहीं है, इसलिए InitializeComponent() और Run() दोनों को कॉल करने के लिए App.Main() को कॉल किया जाना चाहिए। मैं वीएस -2008/.NET3.5 का उपयोग कर रहा हूं, अगर इससे कोई फर्क पड़ता है। ध्यान दें कि System.Windows.Aplication खुद InitializeComponent को कॉल नहीं कर सकता है, क्योंकि InitializeComponent केवल व्युत्पन्न वर्ग में मौजूद है और गैर-वर्चुअल है। यह स्टार्टअप ईवेंट को भी फ़ायर नहीं करेगा क्योंकि यह संभव नहीं है कि कन्स्ट्रक्टर रिटर्न के बाद तक किसी ने उस घटना की सदस्यता ली हो। – Qwertie

19

आमतौर पर मैं इस समर्थन जोड़ने के लिए App.xaml संपादित:

<Application x:Class="SomeNamespace.App" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Startup="Application_Startup"> 

प्रासंगिक हिस्सा होने मैं App.xaml.cs में एक ईवेंट हैंडलर के साथ Startup को StartupUri से बदल दिया है। यहाँ एक उदाहरण है:

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     int verbose = 0; 
     var optionSet = new OptionSet 
     { 
      { "v|verbose", "verbose output, repeat for more verbosity.", 
        arg => verbose++ } 
     }; 

     var extra = optionSet.Parse(e.Args); 
     var mainWindow = new MainWindow(verbose); 
     mainWindow.Show(); 
    } 
} 
+0

, जब तक आप इसे कमांड विंडो से चलाते हैं, आपको कोई भी कंसोल नहीं दिखाई देगा। * 'आउटपुट। – user7116

+0

यह दृष्टिकोण मुझे मुख्य विंडो में कन्स्ट्रक्टर तर्कों को पास करने देता है, जो अच्छा है। मैं इसे जोएल के दृष्टिकोण से भी जोड़ सकता हूं। – Qwertie

+0

यह इंगित करने के लिए धन्यवाद कि यह "स्टार्टअप" है और "स्टार्टअप यूरी" नहीं है! –

2

अपनी कस्टम स्थैतिक मुख्य विधि के साथ नई कक्षा बनाएं। इस विधि के अंत में सिर्फ मूल App.Main() WPF द्वारा उत्पन्न फोन:

public class Program 
{ 
    [STAThread] 
    public static void Main(string[] args) 
    { 
     // Your initialization code 
     App.Main(); 
    } 
} 

फिर अपने प्रोजेक्ट की "स्टार्टअप वस्तु" सेट() वर्ग अपने स्थिर मुख्य युक्त करने के लिए स्थापित कर लिया।

11

लोग समस्या यह है कि आपके प्रोग्राम में दो स्थैतिक मुख्य() विधियां हैं, जो संकलक को शिकायत करने का कारण बनती हैं;

  • संकलक है कि आपके स्थिर मुख्य() विधि निष्पादन प्रवेश बिंदु-सेट अपने प्रोजेक्ट की "स्टार्टअप वस्तु" वर्ग अपने स्थिर मुख्य युक्त करने के लिए की स्थापना की जानी चाहिए बताओ(): इस को हल करने के में से एक निम्न प्रयास करें विधि (समाधान एक्सप्लोरर में प्रोजेक्ट पर राइट-क्लिक करें, "गुण" चुनें, फिर "एप्लिकेशन" टैब के अंतर्गत "स्टार्टअप ऑब्जेक्ट" सेटिंग देखें)।
  • App.g.cs की स्थिर मुख्य() विधि-ऑटो समाधान एक्सप्लोरर की ऑटो-पीढ़ी को बंद करें, App.xaml पर राइट क्लिक करें, "गुण" चुनें, फिर "एप्लिकेशनडिफिनिशन" से "क्रिया बनाएं" में बदलें "।
+1

धन्यवाद का उपयोग कर सकते हैं; दूसरा बुलेट प्वाइंट महत्वपूर्ण था - संक्षेप में वहां से दूर रखा! – Jeb

0

एक कस्टम मुख्य() का उपयोग करके आप समस्याएं चला सकते हैं क्योंकि स्टार्टअपयूरी सेट नहीं है।

आप इस का उपयोग अपने ऐप कक्षा में सिर दर्द के बिना इसे स्थापित करने के लिए कर सकते हैं (मत भूलना App.xaml से StartupUri को हटा दें और पृष्ठ के लिए अपनी कार्रवाई बिल्ड स्थापित करने के लिए): इस दृष्टिकोण के साथ हालांकि

[STAThread] 
static void Main() 
{ 
    App app = new App(); 
    app.InitializeComponent(); 
    app.Run(); 
} 

protected void OnStartup(object sender, StartupEventArgs e) 
{ 
     var toUri = new UriTypeConverter(); 
     StartupUri = (Uri)toUri.ConvertFrom("MainWindow.xaml"); 
... 
} 
संबंधित मुद्दे