윈폼으로 개발시 UI 디자인을 하다보면 코드를 매번 수정할 때 마다 종료 => 디버깅 재시작이 매우 번거로운 경우가 있다.
그래서 예전부터 개인적으로 사용하던 방법이 있는데, Property Grid 를 런타임에 표시해서 일부 컨트롤의 속성을 변경하면 나름 좀 편하다.
아래 스크린샷을 보면 우측 상단 콤보 박스에 나열된 컨트롤 목록을 볼 수 있다.
컨트롤을 선택하면 해당 컨트롤의 속성이 하단 Property Grid 에 표시가 되고,
Property Grid 에서 속성을 변경하면 좌측 화면에 바로 바로 반영된다.
UI 디자인 할때 위치나 크기 때문에 매번 재실행 하는것 보다 이렇게 미리 한번에 확인하면 좀 더 편리하게 작업이 가능하다.
Property Grid 를 그대로 사용하기 때문에 Visual Studio 개발환경과 동일한 장점도 있다.

위의 방식대로 구현하기 위한 코드를 간단하게 작성해 봅니다.
먼저 콤보박스에 바인딩할 PropertyItem 이란 Class 와 Runtime Property 화면을 생성할 Extension Class 를 하나 추가합니다.
using System;
using System.Windows.Forms;
namespace RuntimeProperty
{
public class PropertyItem
{
public object Ctl { get; set; }
public string? Display { get; set; }
public PropertyItem(object ctl, string? display)
{
this.Ctl = ctl;
Display = display;
}
public int CompareTo(PropertyItem other)
{
return Convert.ToInt32(Ctl.Equals(other.Ctl));
}
public override string ToString()
{
return Display ?? "Null";
}
}
public static class Extensions
{
#region Show Property
public static void ShowProperty(this object obj, params object[] objOthers)
{
Form frm = new Form();
frm.Text = frm.Name = "Runtime Property";
ComboBox cmb = new ComboBox();
if (obj is Control)
{
((Control)obj).RecursiveControlsAddToCombo(cmb);
}
else
{
cmb.Items.Add(new PropertyItem(obj, $"[{obj.GetType().Name}] - {obj.ToString()}"));
}
if (objOthers != null)
{
foreach (object objOther in objOthers)
{
if (objOther is Control)
{
((Control)objOther).RecursiveControlsAddToCombo(cmb);
}
else
{
cmb.Items.Add(new PropertyItem(obj, $"[{obj.GetType().Name}] - {obj.ToString()}"));
}
}
}
frm.Controls.Add(cmb);
cmb.Dock = DockStyle.Top;
PropertyGrid pg = new PropertyGrid();
frm.Controls.Add(pg);
pg.Dock = DockStyle.Fill;
pg.BringToFront();
cmb.SelectedIndexChanged += (sender, args) => { pg.SelectedObject = ((PropertyItem)cmb.SelectedItem).Ctl; };
if (cmb.Items.Count > 0)
{
cmb.SelectedIndex = 0;
}
//frm.TopMost = true;
frm.Show();
frm.BringToFront();
}
private static void RecursiveControlsAddToCombo(this Control ctl, ComboBox cmb)
{
cmb.Items.Add(new PropertyItem(ctl, $"[{ctl.GetType().Name}] - {ctl.Name}"));
foreach (Control ctlInner in ctl.Controls)
{
ctlInner.RecursiveControlsAddToCombo(cmb);
}
}
#endregion // Show Property
}
}
그 다음은 메인 폼 소스 코드에 Extension Method 를 호출하기 위해 단축키로 실행하는 코드를 추가합니다.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Shift | Keys.P))
{
this.ShowProperty();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
소스 코드는 다음 Github 에 적용되어 있습니다.
0 Comments