.NET 코드가 Visual Studio 디자이너에서 실행 중인지 확인하는 방법
Visual Studio 디자이너에서 Windows Forms 양식을 열 때 코드에 오류가 발생합니다. 내 코드에서 분기하고 디자이너가 양식을 여는 경우 실제 실행되는 경우보다 다른 초기화를 수행하고 싶습니다.
코드가 양식을 여는 디자이너의 일부로 실행 중인지 런타임에 어떻게 확인할 수 있습니까?
"디자인 모드"에 있는지 확인하려면 :
- Windows Forms 구성 요소 (및 컨트롤)에는 DesignMode 속성이 있습니다.
- Windows Presentation Foundation 컨트롤은 IsInDesignMode 연결된 속성을 사용해야합니다 .
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
// Design time logic
}
Control.DesignMode 속성은 아마도 당신이 찾고있는 것입니다. 디자이너에서 컨트롤의 부모가 열려 있는지 여부를 알려줍니다.
대부분의 경우 잘 작동하지만 예상대로 작동하지 않는 경우가 있습니다. 첫째, 컨트롤 생성자에서 작동하지 않습니다. 둘째, "손자"컨트롤에 대해 DesignMode가 false입니다. 예를 들어 UserControl에서 호스팅되는 컨트롤의 DesignMode는 UserControl이 부모에서 호스팅 될 때 false를 반환합니다.
매우 쉬운 해결 방법이 있습니다. 다음과 같이 진행됩니다.
public bool HostedDesignMode
{
get
{
Control parent = Parent;
while (parent!=null)
{
if(parent.DesignMode) return true;
parent = parent.Parent;
}
return DesignMode;
}
}
그 코드를 테스트하지 않은,하지만 해야 작동합니다.
가장 신뢰할 수있는 접근 방식은 다음과 같습니다.
public bool isInDesignMode
{
get
{
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
bool res = process.ProcessName == "devenv";
process.Dispose();
return res;
}
}
이 작업을 수행하는 가장 안정적인 방법은 DesignMode 속성을 무시하고 응용 프로그램 시작시 설정되는 고유 한 플래그를 사용하는 것입니다.
수업:
public static class Foo
{
public static bool IsApplicationRunning { get; set; }
}
Program.cs :
[STAThread]
static void Main()
{
Foo.IsApplicationRunning = true;
// ... code goes here ...
}
그런 다음 필요할 때마다 플래그를 확인하십시오.
if(Foo.IsApplicationRunning)
{
// Do runtime stuff
}
else
{
// Do design time stuff
}
디자이너가 이제 자체 프로세스를 가지므로 devenv 접근 방식은 VS2012에서 작동하지 않습니다. 현재 사용중인 솔루션은 다음과 같습니다 ( 'devenv'부분은 레거시를 위해 남아 있지만 VS2010 없이는 테스트 할 수 없습니다) .
private static readonly string[] _designerProcessNames = new[] { "xdesproc", "devenv" };
private static bool? _runningFromVisualStudioDesigner = null;
public static bool RunningFromVisualStudioDesigner
{
get
{
if (!_runningFromVisualStudioDesigner.HasValue)
{
using (System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess())
{
_runningFromVisualStudioDesigner = _designerProcessNames.Contains(currentProcess.ProcessName.ToLower().Trim());
}
}
return _runningFromVisualStudioDesigner.Value;
}
}
Visual Studio Express 2013에서 동일한 문제가 발생했습니다. 여기에서 제안 된 많은 솔루션을 시도했지만 저에게 도움이 된 것은 다른 스레드 에 대한 답변 이었습니다 . 링크가 끊어진 경우 여기에서 반복하겠습니다.
protected static bool IsInDesigner
{
get { return (Assembly.GetEntryAssembly() == null); }
}
using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
bool inDesigner = process.ProcessName.ToLower().Trim() == "devenv";
return inDesigner;
}
나는 위의 코드를 시도했고 (using 문을 추가했습니다) 이것은 나를 위해 어떤 경우에 실패 할 것입니다. 시작시 디자이너가로드하는 양식에 직접 배치 된 usercontrol의 생성자에서 테스트합니다. 그러나 다른 곳에서 작동합니다.
모든 위치에서 나를 위해 일한 것은 다음과 같습니다.
private bool isDesignMode()
{
bool bProcCheck = false;
using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
bProcCheck = process.ProcessName.ToLower().Trim() == "devenv";
}
bool bModeCheck = (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime);
return bProcCheck || DesignMode || bModeCheck;
}
약간 과잉 일 수도 있지만 작동하므로 나에게 충분합니다.
위에서 언급 한 예제의 성공은 bModeCheck이므로 DesignMode가 잉여 일 수 있습니다.
/// <summary>
/// Are we in design mode?
/// </summary>
/// <returns>True if in design mode</returns>
private bool IsDesignMode() {
// Ugly hack, but it works in every version
return 0 == String.CompareOrdinal(
"devenv.exe", 0,
Application.ExecutablePath, Application.ExecutablePath.Length - 10, 10);
}
해킹이지만 VB.NET을 사용 하고 Visual Studio 내에서 실행할 때 My.Application.Deployment.CurrentDeployment 는 아직 배포하지 않았기 때문에 Nothing이됩니다. C #에서 동등한 값을 확인하는 방법을 잘 모르겠습니다.
UserControls에서 다음 코드를 사용하고 작업을 수행합니다. 다른 구성원이 지적한대로 사용자 지정 사용자 컨트롤을 사용하는 앱에서는 DesignMode 만 사용하면 작동하지 않습니다.
public bool IsDesignerHosted
{
get { return IsControlDesignerHosted(this); }
}
public bool IsControlDesignerHosted(System.Windows.Forms.Control ctrl)
{
if (ctrl != null)
{
if (ctrl.Site != null)
{
if (ctrl.Site.DesignMode == true)
return true;
else
{
if (IsControlDesignerHosted(ctrl.Parent))
return true;
else
return false;
}
}
else
{
if (IsControlDesignerHosted(ctrl.Parent))
return true;
else
return false;
}
}
else
return false;
}
DesignMode
컨트롤 의 속성을 확인합니다 .
if (!DesignMode)
{
//Do production runtime stuff
}
구성 요소가 아직 초기화되지 않았기 때문에 생성자에서 작동하지 않습니다.
System.ComponentModel.Component.DesignMode == true
System.Diagnostics.Debugger.IsAttached
프로젝트를 실행할 때 이름에 ".vshost"가 추가됩니다.
그래서 이것을 사용합니다.
public bool IsInDesignMode
{
get
{
Process p = Process.GetCurrentProcess();
bool result = false;
if (p.ProcessName.ToLower().Trim().IndexOf("vshost") != -1)
result = true;
p.Dispose();
return result;
}
}
그것은 나를 위해 작동합니다.
디버그 모드에서 실행하는 것이 실제로 간주되는지 확실하지 않지만 쉬운 방법은 if
그 checkes에 대한 코드에서 문을 System.Diagnostics.Debugger.IsAttached
.
디자인 타임에 전혀 필요하지 않은 속성을 만든 경우 DesignerSerializationVisibility를 사용할 수 있습니다. 특성을 사용하고이를 Hidden으로 설정할 수 있습니다. 예를 들면 :
protected virtual DataGridView GetGrid()
{
throw new NotImplementedException("frmBase.GetGrid()");
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int ColumnCount { get { return GetGrid().Columns.Count; } set { /*Some code*/ } }
양식을 변경 NotImplementedException()
하고 저장하려고 할 때마다 Visual Studio 충돌이 중지되었습니다 . 대신 Visual Studio는이 속성을 직렬화하지 않으려는 것을 알고 있으므로 건너 뛸 수 있습니다. 양식의 속성 상자에 이상한 문자열 만 표시되지만 무시해도되는 것 같습니다.
이 변경 사항은 다시 빌드 할 때까지 적용되지 않습니다.
폼이나 컨트롤에있는 경우 DesignMode 속성을 사용할 수 있습니다.
if (DesignMode)
{
DesignMode Only stuff
}
최소한 이전 버전의 Visual Studio에서는 DesignMode 속성이 버그가있는 것으로 나타났습니다. 따라서 다음 논리를 사용하여 직접 만들었습니다.
Process.GetCurrentProcess().ProcessName.ToLower().Trim() == "devenv";
일종의 해킹이라고 알고 있지만 잘 작동합니다.
문제를 해결하기 위해 다음과 같이 코딩 할 수도 있습니다.
private bool IsUnderDevelopment
{
get
{
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
if (process.ProcessName.EndsWith(".vshost")) return true;
else return false;
}
}
다음은 또 하나입니다.
//Caters only to thing done while only in design mode
if (App.Current.MainWindow == null){ // in design mode }
//Avoids design mode problems
if (App.Current.MainWindow != null) { //applicaiton is running }
After testing most of the answers here, unfortunately nothing worked for me (VS2015). So I added a little twist to JohnV's answer, which didn't work out of the box, since DesignMode is a protected Property in the Control class.
First I made an extension method which returns the DesignMode's Property value via Reflection:
public static Boolean GetDesignMode(this Control control)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
PropertyInfo prop = control.GetType().GetProperty("DesignMode", bindFlags);
return (Boolean)prop.GetValue(control, null);
}
and then I made a function like JohnV:
public bool HostedDesignMode
{
get
{
Control parent = Parent;
while (parent != null)
{
if (parent.GetDesignMode()) return true;
parent = parent.Parent;
}
return DesignMode;
}
}
This is the only method that worked for me, avoiding all the ProcessName mess, and while reflection should not be used lightly, in this case it did all the difference! ;)
EDIT:
You can also make the second function an extension method like this:
public static Boolean IsInDesignMode(this Control control)
{
Control parent = control.Parent;
while (parent != null)
{
if (parent.GetDesignMode())
{
return true;
}
parent = parent.Parent;
}
return control.GetDesignMode();
}
/// <summary>
/// Whether or not we are being run from the Visual Studio IDE
/// </summary>
public bool InIDE
{
get
{
return Process.GetCurrentProcess().ProcessName.ToLower().Trim().EndsWith("vshost");
}
}
Here's a flexible way that is adaptable to where you compile from as well as whether or not you care which mode you're in.
string testString1 = "\\bin\\";
//string testString = "\\bin\\Debug\\";
//string testString = "\\bin\\Release\\";
if (AppDomain.CurrentDomain.BaseDirectory.Contains(testString))
{
//Your code here
}
ReferenceURL : https://stackoverflow.com/questions/73515/how-to-tell-if-net-code-is-being-run-by-visual-studio-designer
'programing' 카테고리의 다른 글
앱 스크립트를 사용하여 Google 스프레드 시트의 셀 내부에 UI를 어떻게 추가합니까? (0) | 2021.01.05 |
---|---|
nib / storyboard의 UITextView에서 새 줄을 만드는 방법은 무엇입니까? (0) | 2021.01.05 |
두 배열을 해시로 결합 (0) | 2021.01.05 |
TextInputLayout은 EditText에서 프로그래밍 방식으로 힌트를 제공하는 데 효과가 없습니다. (0) | 2021.01.05 |
iOS 10의 푸시 알림 문제 (0) | 2021.01.05 |