可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Following-on from this question, is it possible to detect whether one is in design or runtime mode from within an object\'s constructor?
I realise that this may not be possible, and that I\'ll have to change what I want, but for now I\'m interested in this specific question.
回答1:
You can use the LicenceUsageMode enumeration in the System.ComponentModel
namespace:
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
回答2:
Are you looking for something like this:
public static bool IsInDesignMode()
{
if (Application.ExecutablePath.IndexOf(\"devenv.exe\", StringComparison.OrdinalIgnoreCase) > -1)
{
return true;
}
return false;
}
You can also do it by checking process name:
if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == \"devenv\")
return true;
回答3:
Component ... as far as I know does not have the DesignMode property. This property is provided by Control. But the problem is when CustomControl is located in a Form in the designer, this CustomControl is running in runtime mode.
I have experienced that the DesignMode property works correct only in Form.
回答4:
IMPORTANT
There is a difference of using Windows Forms or WPF!!
They have different designers and and need different checks.
Additionally it\'s tricky when you mix Forms and WPF controls. (e.g. WPF controls inside of a Forms window)
If you have Windows Forms only, use this:
Boolean isInWpfDesignerMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
If you have WPF only, use this check:
Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == \"devenv\");
If you have mixed usage of Forms and WPF, use a check like this:
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
}
To see the current mode you can show a MessageBox for debugging:
// show current mode
MessageBox.Show(String.Format(\"DESIGNER CHECK: WPF = {0} Forms = {1}\", isInWpfDesignerMode, isInFormsDesignerMode));
Remark:
You need to add the namespaces System.ComponentModel and System.Diagnostics.
回答5:
You should use Component.DesignMode property. As far as I know, this shouldn\'t be used from a constructor.
回答6:
Controls(Forms, UserControls etc.) inherit Component class
which has bool property DesignMode
so:
if(DesignMode)
{
//If in design mode
}
回答7:
Another interesting method is described on that blog: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode-or-usermode/
Basically, it tests for the executing assembly being statically referenced from the entry assembly. It circumvents the need to track assembly names (\'devenv.exe\', \'monodevelop.exe\'..).
However, it does not work in all other scenarios, where the assembly is dynamically loaded (VSTO being one example).
回答8:
With cooperation of the designer... It can be used in Controls, Components, in all places
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(
lines should be removed. It only makes me sure it works correctly.
回答9:
This is the method I used in my project:
//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
;
}
Attention!!!: The code returned bool is indicating NOT in design mode!
回答10:
private void CtrlSearcher_Load(object sender, EventArgs e)
{
if(!this.DesignMode) InitCombos();
}
回答11:
The LicenseManager solution does not work inside OnPaint, neither does this.DesignMode. I resorted to the same solution as @Jarek.
Here\'s the cached version:
private static bool? isDesignMode;
private static bool IsDesignMode()
{
if (isDesignMode == null)
isDesignMode = (Process.GetCurrentProcess().ProcessName.ToLower().Contains(\"devenv\"));
return isDesignMode.Value;
}
Be aware this will fail if you\'re using any third party IDE or if Microsoft (or your end-user) decide to change the name of the VS executable to something other than \'devenv\'. The failure rate will be very low, just make sure you deal with any resulting errors that might occur in the code that fails as a result of this and you\'ll be fine.
回答12:
If you want to run some lines when it is running but not in the Visual Studio designer, you should implement the DesignMode property as follows:
// 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();
}