कंट्रोल के कंस्ट्रक्टर से डिजाइन मोड का पता लगाना


99

बाद-ऑन से इस सवाल का , यह एक एक वस्तु के निर्माता के भीतर से डिजाइन या क्रम मोड में है कि क्या पता लगाने के लिए संभव है?

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

जवाबों:


192

आप नामस्थान में LicenceUsageMode गणना का उपयोग कर सकते हैं System.ComponentModel:

bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);

2
सुरुचिपूर्ण समाधान, यह C # कार्यक्षमता से बेहतर काम करता है ISite.DesignMode
56ka

10
@ फ़िलिप कुनक: अगर यह ऑनपैंट में काम नहीं करता है, तो आप कंस्ट्रक्टर में इस स्थिति की जांच कर सकते हैं और इसे क्लास फ़ील्ड में स्टोर कर सकते हैं।
आईएमआईएल

3
उपयोगकर्ता नियंत्रण में WndProc को ओवरराइड करते समय यह भी काम नहीं करता है। @ िमिल सुझाव का उपयोग करना है
मैट

1
निर्माण में डाल एक अच्छा विचार है IMil, यह मेरे लिए काम किया .. मैं इसे एक स्थिर वर्ग क्षेत्र पर डालने की कोशिश की, लेकिन (मुझे लगता है) स्थिर वर्ग फ़ील्ड प्रारंभ में जब आप उन्हें बुलाया, तो एक सुरक्षित समाधान नहीं ..
इब्राहिम Ozdemir

22

क्या आप कुछ इस तरह की तलाश कर रहे हैं:

public static bool IsInDesignMode()
{
    if (Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1)
    {
        return true;
    }
    return false;
}

आप इसे प्रक्रिया नाम की जाँच करके भी कर सकते हैं:

if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
   return true;

4
OnPaint में काम करता है, व्युत्पन्न वर्ग, निर्माता, आदि अभी तक सबसे अच्छा समाधान है।
फिलिप कुनक

14
IMHO, यह एक बदसूरत समाधान की तरह दिखता है।
कैमिलो मार्टिन

5
ध्यान संभव स्मृति रिसाव यहाँ। प्रक्रिया का निपटारा किया जाना चाहिए।
nalply

7
जबकि मुझे यकीन है कि यह अधिकांश उपयोग के मामलों में ठीक काम करेगा, इस समाधान में एक प्रमुख दोष है: विज़ुअल स्टूडियो केवल डिजाइनर होस्ट नहीं है (कम से कम सिद्धांत में)। इसलिए, यह समाधान केवल तभी काम करेगा जब आपके डिजाइनर को एक एप्लिकेशन नाम से होस्ट किया जाए devenv
स्टैक्स -

2
वर्तमान में स्वीकृत उत्तर के विपरीत VS2013 पर काम करता है।
मोबि डिस्क

9

घटक ... जहाँ तक मुझे पता है कि DesignMode संपत्ति नहीं है। यह संपत्ति नियंत्रण द्वारा प्रदान की जाती है। लेकिन समस्या तब है जब CustomControl डिजाइनर में एक फॉर्म में स्थित है, यह CustomControl रनटाइम मोड में चल रहा है।

मैंने अनुभव किया है कि DesignMode संपत्ति केवल फॉर्म में सही काम करती है।


पारितोषिक के लिए धन्यवाद! मैंने पहले कभी महसूस नहीं किया, लेकिन यह सही समझ में आता है। एड्रिअनबैंक द्वारा प्रदान की गई लाइसेंस प्रबंधक विधि का उपयोग करना इन मामलों में एकदम सही काम करता है, जहां नियंत्रण दूसरे नियंत्रण / रूप में एम्बेडेड होता है। प्रत्येक के लिए +1!
जोश स्ट्रिब्लिंग

1
+1 आप बिल्कुल सही हैं, यह मेरा अनुभव भी रहा है। जब आप किसी उपयोगकर्ता नियंत्रण को किसी प्रपत्र पर रखते हैं, तो कोई भी माउसइंटर या लोड ईवेंट हैं। DesignMode अभी भी गलत होगा क्योंकि आप इस नियंत्रण के लिए designmode में नहीं हैं। मेरे अनुभव में यह दृश्य स्टूडियो को बहुत मुश्किल से क्रैश करने का कारण बनता है।
काइल बी

8

नियंत्रण (प्रपत्र, उपयोगकर्ता नियंत्रक आदि) Component classजो विरासत में मिले bool property DesignModeहैं:

if(DesignMode)
{
  //If in design mode
}

4
जब रचनाकार चलता है, तो ओपी का प्रारंभिक अंक उर्फ ​​सेट नहीं होता है। पहले क्षण में आप इसका उपयोग कर सकते हैं OnHandleCreated
रे

8

जरूरी

विंडोज फॉर्म या WPF का उपयोग करने का अंतर है !!

उनके पास अलग-अलग डिज़ाइनर हैं और अलग-अलग चेक की ज़रूरत है । इसके अलावा जब आप फ़ॉर्म और WPF नियंत्रणों को मिलाते हैं तो यह बहुत मुश्किल होता है। (उदा। प्रपत्र विंडो के अंदर WPF नियंत्रण)

यदि आपके पास केवल Windows प्रपत्र हैं , तो इसका उपयोग करें:

Boolean isInWpfDesignerMode   = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);

यदि आपके पास केवल WPF है , तो इस चेक का उपयोग करें:

Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");

यदि आपके पास फ़ॉर्म और WPF का मिश्रित उपयोग है, तो इस तरह से एक चेक का उपयोग करें:

Boolean isInWpfDesignerMode   = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");

if (isInWpfDesignerMode || isInFormsDesignerMode)
{
    // is in any designer mode
}
else
{
    // not in designer mode
}

वर्तमान मोड देखने के लिए आप डिबगिंग के लिए एक संदेश बॉक्स दिखा सकते हैं:

// show current mode
MessageBox.Show(String.Format("DESIGNER CHECK:  WPF = {0}   Forms = {1}", isInWpfDesignerMode, isInFormsDesignerMode));

टिप्पणी:

आपको नामस्थानों को जोड़ने की जरूरत है । System.ComponentModel और System.Diagnostics


मुझे लगता है कि आपका नामकरण भ्रामक है। WinForms के लिए उपयोग करते समय नामकरण 'isInWpfDesignerMode' है और WPF के लिए यह 'isInFormsDesignerMode' है
M Stoerzel

5

आपको Component.DesignMode प्रॉपर्टी का उपयोग करना चाहिए। जहाँ तक मुझे पता है, इसका इस्तेमाल किसी कंस्ट्रक्टर से नहीं किया जाना चाहिए।


7
यह तब काम नहीं करता है जब आपका नियंत्रण किसी अन्य नियंत्रण या प्रपत्र के अंदर होता है जिसे डिज़ाइन किया जा रहा है।
एरिक

1
वास्तव में यह मेरे घटकों में बहुत अच्छा काम करता है। मुझे हमेशा if (!DesignMode)यह सुनिश्चित करने के लिए ऑनपैंट तरीकों को जोड़ना पड़ा कि यह डिजाइन समय को स्पैम न करे।
बिटरबेल्यू

4

उस ब्लॉग पर एक और दिलचस्प विधि वर्णित है: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode-or -उपयोगकर्ता मोड/

मूल रूप से, यह निष्पादित विधानसभा के लिए परीक्षण करता है जिसे प्रवेश विधानसभा से सांख्यिकीय रूप से संदर्भित किया जाता है। यह असेंबली नामों ('devenv.exe', 'monodevelop.exe' ..) को ट्रैक करने की आवश्यकता को रोकता है।

हालांकि, यह अन्य सभी परिदृश्यों में काम नहीं करता है, जहां विधानसभा गतिशील रूप से भरी हुई है (VSTO एक उदाहरण है)।


लिंक (प्रभावी रूप से) टूटा हुआ है। यह अब इसके बजाय नवीनतम ब्लॉग पोस्ट (वर्तमान में 2016-03) पर रीडायरेक्ट करता है।
पीटर मोर्टेंसन

3

डिजाइनर के सहयोग से ... इसका उपयोग सभी स्थानों पर नियंत्रण, अवयव में किया जा सकता है

    private bool getDesignMode()
    {
        IDesignerHost host;
        if (Site != null)
        {
            host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (host != null)
            {
                if (host.RootComponent.Site.DesignMode) MessageBox.Show("Design Mode");
                else MessageBox.Show("Runtime Mode");
                return host.RootComponent.Site.DesignMode;
            }
        }
        MessageBox.Show("Runtime Mode");
        return false;
    }

MessageBox.Show(लाइनों को हटा दिया जाना चाहिए। यह केवल मुझे सुनिश्चित करता है कि यह सही ढंग से काम करता है।



1

यह वह विधि है जिसका मैंने अपने प्रोजेक्ट में उपयोग किया है:

//use a Property or Field for keeping the info to avoid runtime computation
public static bool NotInDesignMode { get; } = IsNotInDesignMode();
private static bool IsNotInDesignMode()
{
    /*
    File.WriteAllLines(@"D:\1.log", new[]
    {
        LicenseManager.UsageMode.ToString(), //not always reliable, e.g. WPF app in Blend this will return RunTime
        Process.GetCurrentProcess().ProcessName, //filename without extension
        Process.GetCurrentProcess().MainModule.FileName, //full path
        Process.GetCurrentProcess().MainModule.ModuleName, //filename
        Assembly.GetEntryAssembly()?.Location, //null for WinForms app in VS IDE
        Assembly.GetEntryAssembly()?.ToString(), //null for WinForms app in VS IDE
        Assembly.GetExecutingAssembly().Location, //always return your project's output assembly info
        Assembly.GetExecutingAssembly().ToString(), //always return your project's output assembly info
    });
    //*/

    //LicenseManager.UsageMode will return RunTime if LicenseManager.context is not present.
    //So you can not return true by judging it's value is RunTime.
    if (LicenseUsageMode.Designtime == LicenseManager.UsageMode) return false;
    var procName = Process.GetCurrentProcess().ProcessName.ToLower();
    return "devenv" != procName //WinForms app in VS IDE
        && "xdesproc" != procName //WPF app in VS IDE/Blend
        && "blend" != procName //WinForms app in Blend
        //other IDE's process name if you detected by log from above
        ;
}

ध्यान दें !!!: कोड लौटाया गया बूल डिजाइन मोड में नहीं होने का संकेत दे रहा है!


1
    private void CtrlSearcher_Load(object sender, EventArgs e)
    {
           if(!this.DesignMode) InitCombos();
    }

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन समस्या को हल करने के तरीके के बारे में अतिरिक्त संदर्भ प्रदान करता है और यह समस्या को हल करता है ताकि उत्तर के दीर्घकालिक मूल्य में सुधार हो सके।
टियागो मार्टिंस पेरेज

0

लाइसेंस प्रबंधक समाधान OnPaint के अंदर काम नहीं करता है, न ही यह। मैंने @ जेरेक के समान समाधान का सहारा लिया।

यहाँ कैश्ड संस्करण है:

    private static bool? isDesignMode;
    private static bool IsDesignMode()
    {
        if (isDesignMode == null)
            isDesignMode = (Process.GetCurrentProcess().ProcessName.ToLower().Contains("devenv"));

        return isDesignMode.Value;
    }

अगर आप किसी भी तीसरे पक्ष के आईडीई का उपयोग कर रहे हैं या Microsoft (या आपका एंड-यूज़र) वीएस का नाम बदलने के लिए 'devenv' के अलावा किसी अन्य चीज़ को बदलने का निर्णय लेते हैं तो यह विफल हो जाएगा। विफलता की दर बहुत कम होगी, बस यह सुनिश्चित करें कि आप किसी भी परिणामी त्रुटियों से निपटें जो कोड में हो सकती है जो इसके परिणामस्वरूप विफल हो जाती है और आप ठीक हो जाएंगे।


0

यदि आप कुछ लाइनों को चलाना चाहते हैं, लेकिन यह विजुअल स्टूडियो डिजाइनर में नहीं है, तो आपको DesignMode प्रॉपर्टी को इस प्रकार लागू करना चाहिए:

// this code is in the Load of my UserControl
if (this.DesignMode == false)
{
    // This will only run in run time, not in the designer.
    this.getUserTypes();
    this.getWarehouses();
    this.getCompanies();
}

0

डिफ़ॉल्ट रूप से सक्षम किए गए टाइमर कस्टम / उपयोगकर्ता नियंत्रणों का उपयोग करते समय क्रैश का कारण बन सकते हैं। उन्हें डिफ़ॉल्ट रूप से अक्षम करें, और डिज़ाइन मोड की जाँच के बाद ही सक्षम करें

   public chartAdapter()
    {
        try
        {

            //Initialize components come here
            InitializeComponent();

            //Design mode check
            bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
            if (designMode)
                return;

            //Enable timers ONLY after designmode check, or else crash
            timerAutoConnect.Enabled = timerDraw.Enabled = true;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.