2014-11-16 5 views
1

У меня есть настраиваемая форма, которая расширяет форму и переопределяет метод OnPaint, чтобы нарисовать форму в определенном проекте с помощью Темы. У меня есть пользовательский класс «Тема», который содержит четыре цвета для установки на форме:Пользовательская форма Значение свойства сохраняет сброс во время выполнения

public class Theme 
{ 
    public Color BackColor { get; set; } 
    public Color MouseHoverColor { get; set; } 
    public Color ThemeColor { get; set; } 
    public Color ForeColor { get; set; } 
} 

Тема имеет пользовательский UITypeEditor, который использует пользовательский редактор темы с помощью цветных сборщиков, которые я протестирована и работает отлично:

public class ThemeTypeEditor : UITypeEditor 
{ 
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
    { 
     return UITypeEditorEditStyle.Modal; 
    } 

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) 
    { 
     var editor = new ThemeEditor((CustomForm) context.Instance); 

     if (editor.ShowDialog() == DialogResult.OK) 
     { 
      return editor.Theme; 
     } 

     return base.EditValue(context, provider, value); 
    } 
} 

у меня также есть статический класс «тема», который содержит тему по умолчанию для формы использования:

public static class Themes 
{ 
    public static Theme DarkGreen = new Theme 
    { 
     BackColor = Color.FromArgb(53, 53, 53), 
     ForeColor = Color.FromArgb(237, 234, 235), 
     MouseHoverColor = Color.FromArgb(65,65,65), 
     ThemeColor = Color.FromArgb(32, 203, 88) 
    }; 
} 

И в моей пользовательской форме, у меня есть это свойство, которое используется OnPaint метод:

private Theme theme = (Theme) Themes.DarkGreen; 
[Category("Appearance"), 
Description("Specifies the Theme for this form."), 
Editor(typeof(ThemeTypeEditor), typeof(UITypeEditor)), 
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
public Theme Theme { 
    get { return theme; } 
    set { 
     theme = value; 
     Invalidate(); 
    } 
} 

Однако, когда я пытаюсь изменить тему в конструкторе по новой форме, которая простирается CustomForm, дизайнер не обновляет и тема возвращается к Themes.DarkGreen во время выполнения. Я не уверен, что я должен делать для этого, так как я понимаю, что я должен иметь возможность изменять тему и видеть изменения во время разработки и времени выполнения. Как указано, метод OnPaint использует поле «Тема» выше, чтобы нарисовать цвет фона формы и дополнительную раскрашенную графику. Любая помощь приветствуется.

EDIT:

Форма в изменениях конструктора формы, когда проект был построен и работает, но фактическая форма работает остается неизменной. Я хотел бы, чтобы изменения были немедленно видны при применении темы и для ее применения в встроенном приложении.

EDIT 2:

Я решил показать MessageBox для отладки этого. Я поместил его в свой метод EditValue ThemeTypeEditor до того, как он вернул новую тему, и, конечно же, он работает, и значения темы верны. Тем не менее, я также разместил MessageBox в свой настройке свойств темы после Invalidate() ;, и ничего не отображается. Это похоже на то, что набор свойств вообще не называется.

ответ

0

Я решил это, изменив различные вещи. Первое было создание базового класса с именем ComponentBase, который расширяет компонент и реализация INotifyPropertyChanged:

public class ComponentBase : Component, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    private void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null) 
    { 
     if (EqualityComparer<T>.Default.Equals(field, value)) return false; 

     var changeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService; 
     if (changeService != null) 
      changeService.OnComponentChanged(this, TypeDescriptor.GetProperties(this).Find(propertyName, false), field, value); 

     field = value; 
     OnPropertyChanged(propertyName); 

     return true; 
    } 
} 

Это означало, что мне нужно, чтобы удалить природу Авто-свойство свойств моей темы. Я изменил редактор каждого цвета в тему так, чтобы он использовал пипетку, и дал им DesignerSerializationVisibility видимого:

public sealed partial class Theme : ComponentBase 
{ 
    private Color backgroundColor; 

    [Category("Theme")] 
    [DisplayName("Background Color")] 
    [Editor(typeof (ThemeTypeEditor), typeof (UITypeEditor))] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
    [TypeConverter(typeof (ThemeColorConverter))] 
    public Color BackgroundColor 
    { 
     get { return backgroundColor; } 
     set { SetField(ref backgroundColor, value); } 
    } 

    private Color foregroundColor; 

    [Category("Theme")] 
    [DisplayName("Foreground Color")] 
    [Editor(typeof(ThemeTypeEditor), typeof(UITypeEditor))] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
    [TypeConverter(typeof(ThemeColorConverter))] 
    public Color ForegroundColor 
    { 
     get { return foregroundColor; } 
     set { SetField(ref foregroundColor, value); } 
    } 

    private Color highlightColor; 

    [Category("Theme")] 
    [DisplayName("Highlight Color")] 
    [Editor(typeof(ThemeTypeEditor), typeof(UITypeEditor))] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
    [TypeConverter(typeof(ThemeColorConverter))] 
    public Color HighlightColor 
    { 
     get { return highlightColor; } 
     set { SetField(ref highlightColor, value); } 
    } 

    private Color borderColor; 

    [Category("Theme")] 
    [DisplayName("Border Color")] 
    [Editor(typeof(ThemeTypeEditor), typeof(UITypeEditor))] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
    [TypeConverter(typeof(ThemeColorConverter))] 
    public Color BorderColor 
    { 
     get { return borderColor; } 
     set { SetField(ref borderColor, value); } 
    } 

    private Color themeColor; 

    [Category("Theme")] 
    [DisplayName("Theme Color")] 
    [Editor(typeof(ThemeTypeEditor), typeof(UITypeEditor))] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
    [TypeConverter(typeof(ThemeColorConverter))] 
    public Color ThemeColor 
    { 
     get { return themeColor; } 
     set { SetField(ref themeColor, value); } 
    } 
} 

Как тема в моей пользовательской форме использует DesignerSerializationVisibility.Content, это позволяет коду быть сгенерированный для содержимого темы, что означает, что отдельные цвета в теме обновляются как время разработки, так и время выполнения:

private Theme theme; 

[DisplayName("Theme")] 
[Category("Appearance")] 
[Description("Specifies the Theme for this form.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
public Theme Theme 
{ 
    get { return theme; } 
    set 
    { 
     theme = value; 
     Invalidate(); 
    } 
} 
Смежные вопросы