2009-06-12 4 views
3

다음 문제에 대한 도움이 필요합니다.다른 속성에서 선택한 값의 인덱스를 저장하는 속성을 만드는 방법은 무엇입니까?

두 가지 속성이있는 클래스가 있습니다.

private byte m_selectedValue; 
public byte SelectedValue 
{ 
    get { return m_selectedValue; } 
    set { m_selectedValue = value; } 
} 

private string[] m_possibleValues; 
public string[] PossibleValues 
{ 
    get { return m_possibleValues; } 
    set { m_possibleValues = value; } 
} 

PossibleValues는 선택 가능한 값 목록을 저장합니다. SelectedValue는 실제로 선택된 값의 색인을 포함합니다.

이 상태에서 속성 편집기는 선택한 값의 색인을 표시합니다. Enum 속성에 사용 된 것과 같은 스타일 인 속성 표에서 콤보 상자를 사용하여 값을 선택하고 싶습니다. 콤보 상자의 목록은 PossibleValues ​​속성에서 채워집니다.

이 기사 (http://www.codeproject.com/KB/cpp/UniversalDropdownEditor.aspx)의 도움으로 PossibleValues ​​속성의 값으로 속성 표에 콤보 상자를 표시하는 사용자 지정 편집기를 만들었습니다. 값을 선택할 수도 있지만 여전히 속성 그리드는 값 자체 대신 값의 인덱스를 표시합니다.

이 편집기의 수정 된 소스 (원본이 CodeProject의에서입니다)입니다 : 물론

public class EnumParamValuesEditor : UITypeEditor 
{ 
    private IWindowsFormsEditorService edSvc; 

    public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) 
    { 
     if ((context != null) && (context.Instance != null)) 
      return UITypeEditorEditStyle.DropDown; 
     return UITypeEditorEditStyle.None; 
    } 

    public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value) 
    { 
     if ((context == null) || (provider == null) || (context.Instance == null)) 
      return base.EditValue(provider, value); 
     edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); 
     if (edSvc == null) 
      return base.EditValue(provider, value); 
     ListBox lst = new ListBox(); 
     PrepareListBox(lst, context); 
     lst.SelectedIndex = (byte)value; 
     edSvc.DropDownControl(lst); 
     if (lst.SelectedItem == null) 
      value = null; 
     else 
      value = (byte)lst.SelectedIndex; 
     return value; 
    } 

    private void PrepareListBox(ListBox lst, ITypeDescriptorContext context) 
    { 
     lst.IntegralHeight = true; 
     string[] coll = ((EnumTerminalParam)context.Instance).PossibleValues; 
     if (lst.ItemHeight > 0) 
     { 
      if ((coll != null) && (lst.Height/lst.ItemHeight < coll.Length)) 
      { 
       int adjHei = coll.Length * lst.ItemHeight; 
       if (adjHei > 200) 
        adjHei = 200; 
       lst.Height = adjHei; 
      } 
     } 
     else 
      lst.Height = 200; 
     lst.Sorted = true; 
     FillListBoxFromCollection(lst, coll); 
     lst.SelectedIndexChanged += new EventHandler(lst_SelectedIndexChanged); 
    } 

    void lst_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (edSvc == null) 
      return; 
     edSvc.CloseDropDown(); 
    } 

    public void FillListBoxFromCollection(ListBox lb, ICollection coll) 
    { 
     lb.BeginUpdate(); 
     lb.Items.Clear(); 
     foreach (object item in coll) 
      lb.Items.Add(item); 
     lb.EndUpdate(); 
     lb.Invalidate(); 
    } 

} 

, 그것은 정확하게 어떤 상황을 처리하기 위해 추가 수정이 필요합니다 (예 PossibleValues가 비어 있습니다.).

속성 편집기에서 SelectedValue 대신 PossibleValues ​​[SelectedValue]를 표시 할 수 있습니까?

답변

1

SelectedValue 속성에 사용자 지정 TypeConverter를 연결하고 PossibleValues를 찾아보기 할 수 없게해야합니다. TypeConverter는 int 대신 PropertyGrid에 문자열을 표시합니다. 기본적으로 CanConvertFrom, CanConvertTo, ConvertFrom 및 ConvertTo를 재정의해야합니다. 사용자 정의 문자열을 가져 오려면 이러한 메서드에 전달 된 context 인수를 사용하고 대상 인스턴스에서 PossibleValues ​​속성을 호출합니다. 그렇게해야합니다. 여기에 사용자 정의 UITypeEditor가 필요하지 않은 것 같습니다.

+0

GetStandardValuesSupported 및 GetStandardValues는 속성 편집기에서 콤보 상자를 표시하는 데 사용됩니다. 불행히도 GetStandardValues는 최소한 http://msdn.microsoft.com/en-us/library/ayybcxe5.aspx에 따라 속성 자체와 같은 형식의 요소를 가진 컬렉션을 반환해야합니다. ConvertFrom 또는 ConvertTo 메서드를 사용하여 콤보 상자를 표시하는 속성 편집기를 만들려면 어떻게해야합니까? – starobrno

+0

예, GetStandardValues는 네이티브 형식 (바이트)을 반환합니다. 그리고 이것은 콤보 박스를 유발할 것입니다. ConvertFrom 및 ConvertTo는 사용자 지정 문자열에 대한 변환을 수행하여 바이트가 아닌 문자열이 목록에 표시되도록합니다. –

0

두 개의 별도 속성 대신 사전 형식으로 묶어 두는 것이 좋습니다. 이 경우 훨씬 더 사용하기 쉽습니다. 인덱스를 키로, 문자열 []을 값으로 사용하십시오. 인덱스의 바이트로만 제한하지 마십시오.

+0

PossibleValues를 string []에서 Dictionary 으로 변경하면 여전히 현재 선택된 값을 저장하는 속성이 필요합니다. 응용 프로그램은 외부 장치에서 정보를 처리하고 처리 후 정보가 다시 전송됩니다. 이 장치는 0에서 255 사이의 값만 받아들이 기 때문에 바이트 데이터 형식을 사용합니다. – starobrno

관련 문제