我有一个名为CustomControl的类,它继承自System.Windows.Forms.Control。
我还将创建一个名为GraphicsData的新类,其中包含关于CustomControl的所有图形信息(我需要这个因为更容易将数据序列化以保存到数据库、json等)。
在初始化CustomControl对象时(即在构造函数中),它将获取GraphicsData信息,并获得GraphicsData中所有具有值的属性(有时我不想从GraphicsData中初始化所有属性,而是希望它们保留System.Windows.Forms.Control类的默认值)。
问题在于,大多数属性都不可为空,因此我无法检查它们是否为null,所以我不能采用简单的方法:
在我的自定义控件中,我有一个方法:
在初始化CustomControl对象时(即在构造函数中),它将获取GraphicsData信息,并获得GraphicsData中所有具有值的属性(有时我不想从GraphicsData中初始化所有属性,而是希望它们保留System.Windows.Forms.Control类的默认值)。
问题在于,大多数属性都不可为空,因此我无法检查它们是否为null,所以我不能采用简单的方法:
customControl.BackColor = graphicsData.BackColor.HasValue ? graphicsData.BackColor.Value : BackColor;
我当然可以通过创建自己的Nullable类来解决这个问题,但是这样会让代码变得难以理解和混乱。而且,在需要添加新属性时也非常困难。
现在,我认为更加清晰的方法是:
GraphicsData 类:
public class GraphicsData : INotifyPropertyChanged
{
private readonly List<string> _initializedProperties = new List<string>();
public List<string> InitializedProperties { get { return _initializedProperties; } }
public event PropertyChangedEventHandler PropertyChanged;
private Size _size;
private Point _location;
private AnchorStyles _anchor;
private Color _backColor;
private Image _backgroundImage;
private Cursor _cursor;
private Font _font;
private Color _foreColor;
private bool _enabled;
private bool _visible;
public Size Size
{
get { return _size; }
set
{
_size = value;
OnPropertyChanged("Size");
}
}
public Point Location
{
get { return _location; }
set
{
_location = value;
OnPropertyChanged("Location");
}
}
public AnchorStyles Anchor
{
get { return _anchor; }
set
{
_anchor = value;
OnPropertyChanged("Anchor");
}
}
public Color BackColor
{
get { return _backColor; }
set
{
_backColor = value;
OnPropertyChanged("BackColor");
}
}
public Image BackgroundImage
{
get { return _backgroundImage; }
set
{
_backgroundImage = value;
OnPropertyChanged("BackgroundImage");
}
}
public Cursor Cursor
{
get { return _cursor; }
set
{
_cursor = value;
OnPropertyChanged("Cursor");
}
}
public Font Font
{
get { return _font; }
set
{
_font = value;
OnPropertyChanged("Font");
}
}
public Color ForeColor
{
get { return _foreColor; }
set
{
_foreColor = value;
OnPropertyChanged("ForeColor");
}
}
public bool Enabled
{
get { return _enabled; }
set
{
_enabled = value;
OnPropertyChanged("Enabled");
}
}
public bool Visible
{
get { return _visible; }
set
{
_visible = value;
OnPropertyChanged("Visible");
}
}
protected void OnPropertyChanged(string propertyName)
{
if (!_initializedProperties.Contains(propertyName))
_initializedProperties.Add(propertyName);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
在我的自定义控件中,我有一个方法:
public void LoadGraphics()
{
var initializedProperties = graphics.InitializedProperties;
foreach (string propertyName in initializedProperties)
{
var value = graphics.GetType()
.GetProperty(propertyName)
.GetValue(graphics, null);
_customControl.GetType()
.GetProperty(propertyName)
.SetValue(_customControl, value, null);
}
}
我创建了一个名为InitializedProperties的List,并在属性“set”中将属性添加到该列表中。 然后,在我的CustomControl中使用reflection,我可以加载所有已初始化的属性。
我实现了INotifyPropertyChanged,因为我希望在GraphicsData中更改属性时每次都更改customControl属性。
这是我想要做的正确方式吗?我认为反射代码不太易读,并且我担心性能问题。