我有一个自定义表单,它扩展了Form,它覆盖了OnPaint方法,使用Theme在特定设计中绘制表单。我有一个自定义课程"主题"其中包含要在表单上设置的四种颜色:
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方法使用上面的Theme字段绘制表单的背景颜色和其他绘制的图形。任何帮助表示赞赏。
修改
表单设计器中的表单在构建和运行项目时会更改,但实际运行的表单保持不变。我希望在应用主题时立即看到更改,并将其应用于构建的应用程序。
编辑2:
我决定展示一个MessageBox来调试它。在我返回新主题之前,我在ThemeTypeEditor的EditValue方法中放置了一个,当然,它有效,并且主题值是正确的。但是,在Invalidate();之后,我还在我的主题属性设置器中放置了一个MessageBox,并且没有显示任何内容。就像财产的集合根本没有被调用一样。
答案 0 :(得分:0)
我通过改变各种事情来解决这个问题。第一个是创建一个名为ComponentBase的基类,它扩展了Component并实现了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;
}
}
这意味着我需要删除主题属性的自动属性。我更改了主题中每个颜色的编辑器,以便它使用颜色选择器,并为它们提供了Visible的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();
}
}