使用自定义 class 属性 的 Winforms 控件不刷新
Winforms Control using custom class property doesn't refresh
我一直在寻找解决方案,但似乎找不到,尽管我想这可能很简单。
我已经构建了一个自定义控件属性 那是一个 Class。 当我更改任何此 class 属性时,我的控件不会自动刷新(无论是在设计器中还是以编程方式)。有什么方法可以强制执行 Invalidate() 方法吗?
我遵循了一些我发现的提示,但 none 似乎有效。
这是一个代码示例来演示我的内容我正在经历。
这是我的自定义类型。
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TextComponent
{
public TextComponent()
{
Text= string.Empty;
Font = Control.DefaultFont;
ForeColor = Control.DefaultForeColor;
}
[NotifyParentProperty(true)]
public string Text { get; set; }
[NotifyParentProperty(true)]
public Font Font { get; set; }
[NotifyParentProperty(true)]
public Color ForeColor { get; set; }
}
这是我的自定义控件:
public partial class myControl : Control
{
private TextComponent tc = new TextComponent();
protected override void OnPaint(PaintEventArgs pe)
{
pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
GraphicsPath gp = new GraphicsPath();
Rectangle rect = new Rectangle(1, 1, DisplayRectangle.Width - 3, DisplayRectangle.Height - 3);
gp.AddRectangle(rect);
pe.Graphics.FillPath(new SolidBrush(Color.LightCoral), gp);
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
pe.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
pe.Graphics.DrawString(tc.Text, tc.Font, new SolidBrush(tc.ForeColor), rect, sf);
}
base.OnPaint(pe);
}
[Description("The Text Component for the Control"), Category("Text"), NotifyParentPropertyAttribute(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TextComponent TextComponent { get { return tc; } }
public myControl()
{
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new string Text { get { return string.Empty; } }
}
尝试侦听 PropertyChanged 事件以使其正常工作。您必须将 INotifyPropertyChanged 接口添加到 class 并启动它:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TextComponent : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected void OnChanged(string propertyName) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string text = string.Empty;
[NotifyParentProperty(true)]
public string Text {
get { return text; }
set {
text = value;
OnChanged("Text");
}
}
}
然后在你的控件class中监听事件并使你的控件失效:
public myControl() {
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.TextComponent.PropertyChanged += TextComponent_PropertyChanged;
}
void TextComponent_PropertyChanged(object sender, PropertyChangedEventArgs e) {
this.Invalidate();
}
我一直在寻找解决方案,但似乎找不到,尽管我想这可能很简单。
我已经构建了一个自定义控件属性 那是一个 Class。 当我更改任何此 class 属性时,我的控件不会自动刷新(无论是在设计器中还是以编程方式)。有什么方法可以强制执行 Invalidate() 方法吗?
我遵循了一些我发现的提示,但 none 似乎有效。
这是一个代码示例来演示我的内容我正在经历。
这是我的自定义类型。
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TextComponent
{
public TextComponent()
{
Text= string.Empty;
Font = Control.DefaultFont;
ForeColor = Control.DefaultForeColor;
}
[NotifyParentProperty(true)]
public string Text { get; set; }
[NotifyParentProperty(true)]
public Font Font { get; set; }
[NotifyParentProperty(true)]
public Color ForeColor { get; set; }
}
这是我的自定义控件:
public partial class myControl : Control
{
private TextComponent tc = new TextComponent();
protected override void OnPaint(PaintEventArgs pe)
{
pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
GraphicsPath gp = new GraphicsPath();
Rectangle rect = new Rectangle(1, 1, DisplayRectangle.Width - 3, DisplayRectangle.Height - 3);
gp.AddRectangle(rect);
pe.Graphics.FillPath(new SolidBrush(Color.LightCoral), gp);
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
pe.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
pe.Graphics.DrawString(tc.Text, tc.Font, new SolidBrush(tc.ForeColor), rect, sf);
}
base.OnPaint(pe);
}
[Description("The Text Component for the Control"), Category("Text"), NotifyParentPropertyAttribute(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TextComponent TextComponent { get { return tc; } }
public myControl()
{
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new string Text { get { return string.Empty; } }
}
尝试侦听 PropertyChanged 事件以使其正常工作。您必须将 INotifyPropertyChanged 接口添加到 class 并启动它:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TextComponent : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected void OnChanged(string propertyName) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string text = string.Empty;
[NotifyParentProperty(true)]
public string Text {
get { return text; }
set {
text = value;
OnChanged("Text");
}
}
}
然后在你的控件class中监听事件并使你的控件失效:
public myControl() {
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.TextComponent.PropertyChanged += TextComponent_PropertyChanged;
}
void TextComponent_PropertyChanged(object sender, PropertyChangedEventArgs e) {
this.Invalidate();
}