Обнаружение режима конструктора из конструктора элемента управления
следуя этому вопросу, можно ли определить, находится ли он в режиме проектирования или выполнения из конструктора объекта?
Я понимаю, что это может быть невозможно, и что мне придется изменить то, что я хочу, но сейчас меня интересует этот конкретный вопрос.
11 ответов:
можно использовать LicenceUsageMode перечисления в
System.ComponentModelпространство имен:bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
вы ищете что-то вроде этого:
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;
компонент ... насколько я знаю, не имеет свойства DesignMode. Это свойство обеспечивается контролем. Но проблема в том, что пользовательский элемент управления находится в форме в конструкторе, этот пользовательский элемент управления работает в режиме выполнения.
Я испытал, что свойство DesignMode работает правильно только по форме.
важно
есть разница в использовании Windows формы или 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 }чтобы увидеть текущий режим вы можете показать MessageBox для отладки:
// show current mode MessageBox.Show(String.Format("DESIGNER CHECK: WPF = {0} Forms = {1}", isInWpfDesignerMode, isInFormsDesignerMode));замечание:
вам нужно добавить пространства имен
вы должны использовать компонент.Свойство DesignMode. Насколько я знаю, это не должно использоваться из конструктора.
еще один интересный метод описан в этом блоге: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode-or-usermode/
в основном, он проверяет выполнение сборки, на которую статически ссылаются из сборки ввода. Он обходит необходимость отслеживать имена сборок ('devenv.exe', ' монодевелоп.exe'..).
, Он не работает во всех других сценариях, где сборка динамически загружается (VSTO является одним из примеров).
элементы управления (формы, UserControls и др.) наследовать
Component classимеющегоbool property DesignModeтак:if(DesignMode) { //If in design mode }
при сотрудничестве дизайнера... Его можно использовать в элементах управления, компонентах, во всех местах
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(строки должны быть удалены. Это только заставляет меня убедиться, что он работает правильно.
решение LicenseManager не работает внутри OnPaint, так же как и это.DesignMode. Я прибегнул к тому же решению, что и @Jarek.
вот кэшированная версия:
private static bool? isDesignMode; private static bool IsDesignMode() { if (isDesignMode == null) isDesignMode = (Process.GetCurrentProcess().ProcessName.ToLower().Contains("devenv")); return isDesignMode.Value; }имейте в виду, что это не удастся, если вы используете какую-либо стороннюю IDE или если Microsoft (или ваш конечный пользователь) решит изменить имя исполняемого файла VS на что-то другое, чем "devenv". Частота отказов будет очень низкой, просто убедитесь, что вы имеете дело с любыми результирующими ошибками, которые могут возникнуть в код, который не работает в результате этого, и вы будете в порядке.
Если вы хотите запустить некоторые строки, когда он работает, но не в конструкторе Visual Studio, необходимо реализовать свойство 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(); }
Это метод, который я использовал в своем проекте:
//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:.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 ; }внимание!!!: код, возвращенный bool указывает не в режиме конструктора!
Comments