2015-04-16 2 views
2

Я хотел бы иметь элемент управления, который позволяет отображать свойство, если значение другого свойства установлено на определенное значение. Ниже намного упростили пример того, что я хотел:Свойства динамического времени разработки C#

public class CustomButton : Control 
{ 
    private ButtonType _bType = ButtonType.OnOff; 
    private Int32 _minPress = 50; // 50 mS 

    public ButtonType Button_Type 
    { 
     get { return _bType; } 
     set { _bType = value; } 
    } 

    public Int32 Minimum_Press_Time // Only for momentary buttons 
    { 
     get { return _minPress; } 
     set { _minPress = value; } 
    } 

} 
public enum ButtonType 
{ 
    Momentary, 
    OnOff 
} 

При добавлении CustomButton к форме Windows.Forms, то Minimum_Press_Time будет отображаться только в окне свойств, если Button_Type изменяется на ButtonType.Momentary.

Возможно ли такое?

+0

Итак, во время разработки, как бы вы изменили свойство на «Momentary» через окно свойств? Что делать, если пользователь случайно изменил его и хочет изменить его? Похоже на плохой пользовательский опыт, если я не пропущу что-то. Можете ли вы дать реальный сценарий? –

+0

Что я хочу? Если пользователь помещает кнопку в форму и затем устанавливает Button_Type в Momentary, тогда свойство Property_Type появляется в окне свойств и может быть задано. Если пользователь затем устанавливает Button_Type в OnOff, свойство Minimum_Press_Time больше не отображается , хотя значение все еще находится в переменной класса. " Я не думаю, что это возможно. Для моего «реального» класса у меня есть около 15 переменных, которые изменяют, являются ли они действительными в зависимости от выбранного типа. По-видимому, мой выбор состоит в том, чтобы просто показать все свойства (независимо от того, действительны они или нет) или использовать несколько производных классов. –

ответ

1

Да, его можно приблизиться, но это выглядит немного странно. Раньше я делал это на некоторых элементах управления. Вот полный пример того, что вам нужно будет сделать:

public partial class CustomButton : Control 
{ 
    private ButtonType _buttonType = ButtonType.OnOff; 
    private CustomButtonOptions _options = new OnOffButtonOptions(); 

    [RefreshProperties(System.ComponentModel.RefreshProperties.All)] 
    public ButtonType ButtonType 
    { 
     get { return _buttonType; } 
     set 
     { 
      switch (value) 
      { 
       case DynamicPropertiesTest.ButtonType.Momentary: 
        _options = new MomentaryButtonOptions(); 
        break; 
       default: 
        _options = new OnOffButtonOptions(); 
        break; 
      } 
      _buttonType = value; 
     } 
    } 

    [TypeConverter(typeof(ExpandableObjectConverter))] 
    public CustomButtonOptions ButtonOptions 
    { 
     get { return _options; } 
     set { _options = value; } 
    } 

    public CustomButton() 
    { 
     InitializeComponent(); 
    } 
} 

public enum ButtonType 
{ 
    Momentary, 
    OnOff 
} 

public abstract class CustomButtonOptions 
{ 

} 

public class MomentaryButtonOptions : CustomButtonOptions 
{ 
    public int Minimum_Press_Time { get; set; } 

    public override string ToString() 
    { 
     return Minimum_Press_Time.ToString(); 
    } 
} 

public class OnOffButtonOptions : CustomButtonOptions 
{ 
    public override string ToString() 
    { 
     return "No Options"; 
    } 
} 

Так в основном то, что происходит, вы используете ExpandableObjectConverter для преобразования абстрактного типа с набором опций. Затем вы используете атрибут RefreshProperties, чтобы сообщить сетке свойств, что он должен будет обновить свойства после изменения этого свойства.

Это самый простой способ, который я нашел как можно ближе к тому, о чем вы просите. Сетка свойств не всегда обновляется правильно, поэтому иногда рядом с параметрами, не имеющими расширяемых свойств, будет знак «+». Используйте «ToString» в свойствах, чтобы сделать отображение в сетке свойств интеллектуальным.

+0

Я пробовал это, и это не «точно» то, что я хотел, но он обеспечивает то, что мне нужно, поэтому я отмечаю это как мой принятый ответ ... Спасибо –

+0

Не пытаясь сделать типы, которые скомпилированы динамически, это о том, на что вы можете надеяться. WPF обрабатывает его намного лучше, чем WinForms. –