คำถามที่ตามมาจากคำถามนี้เป็นไปได้หรือไม่ที่จะตรวจพบว่าอยู่ในโหมดออกแบบหรือโหมดรันไทม์จากภายในตัวสร้างของวัตถุ
ฉันตระหนักดีว่าสิ่งนี้อาจเป็นไปไม่ได้และฉันจะต้องเปลี่ยนสิ่งที่ฉันต้องการ แต่ตอนนี้ฉันสนใจคำถามเฉพาะนี้
คำตอบ:
คุณสามารถใช้การแจงนับ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;
devenv
ดังนั้นการแก้ปัญหานี้จะทำงานหากนักออกแบบของคุณเป็นเจ้าภาพโดยโปรแกรมที่เรียกว่า
ส่วนประกอบ ... เท่าที่ฉันรู้ไม่มีคุณสมบัติ DesignMode คุณสมบัตินี้จัดทำโดย Control แต่ปัญหาคือเมื่อ CustomControl อยู่ในฟอร์มในตัวออกแบบ CustomControl นี้กำลังทำงานในโหมดรันไทม์
ฉันมีประสบการณ์ว่าคุณสมบัติ DesignMode ทำงานได้ถูกต้องในแบบฟอร์มเท่านั้น
การควบคุม (ฟอร์ม UserControls ฯลฯ ) สืบทอดComponent class
ซึ่งมีbool property DesignMode
ดังนี้:
if(DesignMode)
{
//If in design mode
}
OnHandleCreated
ครั้งแรกที่คุณสามารถใช้มันอยู่ใน
สิ่งสำคัญ
การใช้ Windows FormsหรือWPFมีความแตกต่างกันอย่างไร!!
พวกเขามีนักออกแบบที่แตกต่างกันและและความจำเป็นในการตรวจสอบที่แตกต่างกัน นอกจากนี้ยังยุ่งยากเมื่อคุณผสมฟอร์มและตัวควบคุม WPF (เช่น WPF ควบคุมภายในหน้าต่างแบบฟอร์ม)
หากคุณมี Windows Forms เท่านั้นให้ใช้สิ่งนี้:
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));
สังเกต:
คุณจำเป็นต้องเพิ่ม namespaces System.ComponentModelและSystem.Diagnostics
คุณควรใช้คุณสมบัติ Component.DesignMode เท่าที่ฉันรู้สิ่งนี้ไม่ควรใช้จากตัวสร้าง
if (!DesignMode)
วิธีการ OnPaint เสมอเพื่อให้แน่ใจว่าจะไม่สแปมเวลาออกแบบ
อีกวิธีหนึ่งที่น่าสนใจมีอธิบายไว้ในบล็อกนั้น: 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 เป็นตัวอย่างเดียว)
คุณสามารถใช้สิ่งนี้
if (DesignerProperties.GetIsInDesignMode(this))
{
...
}
ด้วยความร่วมมือของผู้ออกแบบ ... สามารถใช้ใน Controls, Components, ในทุกสถานที่
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(
ควรลบเส้นออก มันทำให้ฉันแน่ใจว่ามันทำงานถูกต้องเท่านั้น
นี่คือวิธีที่ฉันใช้ในโครงการของฉัน:
//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
;
}
ความสนใจ !!!:รหัสที่ส่งคืนบูลแสดงว่าไม่อยู่ในโหมดออกแบบ!
โซลูชัน LicenseManager ไม่ทำงานใน OnPaint ไม่ทำสิ่งนี้ ฉันใช้วิธีแก้ปัญหาเดียวกับ @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();
}
private void CtrlSearcher_Load(object sender, EventArgs e)
{
if(!this.DesignMode) InitCombos();
}
ตัวจับเวลาที่เปิดใช้งานโดยค่าเริ่มต้นอาจทำให้เกิดข้อขัดข้องเมื่อใช้การควบคุมแบบกำหนดเอง / ผู้ใช้ ปิดใช้งานตามค่าเริ่มต้นและเปิดใช้งานหลังจากตรวจสอบโหมดการออกแบบเท่านั้น
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;
ISite.DesignMode
ทางออกที่สวยงามมันทำงานได้ดีกว่าการทำงาน C #