我有以下界面,可以通过自定义控件和表单实现:
public interface IThemeable<T> where T : ITheme
{
T Theme { get; set; }
void ChangeTheme(); // Calls ThemeChangedEvent
}
ITheme
是所有主题都继承自的接口:
public interface ITheme : ICloneable
{
Color ThemeColor { get; set; }
}
如果Parent也是IThemeable
,我希望ThemeColor
个组件能够继承父主题IThemeable
,因此我创建了一个接口来提供此功能:
public interface IThemeableComponent
{
bool InheritTheme { get; set; }
ITheme ParentTheme { get; set; }
void InitializeTheme();
}
在InitializeTheme
内部是我要设置ParentTheme
的位置,所以我理想的是要检查组件的父级是否继承自IThemeable
,如果是,请设置ParentTheme
到父母的主题。但是,因为IThemeable需要通用类型,所以我不能这样做:
// Expander.cs - class Expander : ContainerControl, IThemeable<ExpanderTheme>, IThemeableComponent
private bool _inheritTheme;
public bool InheritTheme
{
get
{
return _inheritTheme;
}
set
{
// Check whether the parent is of type IThemeable
_inheritTheme = Parent.GetType().GetGenericTypeDefinition() == typeof (IThemeable<>) && value;
}
}
public ITheme ParentTheme { get; set; }
public void InitializeTheme()
{
Theme = Themes.ExpanderDefault.Clone() as ExpanderTheme;
if (Parent.GetType().GetGenericTypeDefinition() == typeof (IThemeable<>))
{
ParentTheme = (Parent as IThemeable<>).Theme; // Type argument is missing
}
}
有没有办法可以实现我的目标?或者如果没有,是否有其他方法?
修改
IThemeable是通用的。实现成员应该具有扩展ITheme而不是ITheme本身的指定主题,原因有两个:
使用设计师更改主题。他们还使用编辑器来更改主题。如果使用ITheme
,设计人员将无法确定正在使用的实现主题。
代码需要了解有关主题的更多信息才能正确呈现组件,因为每个主题都有自己独特的属性(例如,FormTheme有Color ControlBoxHoverColor
)。如果使用ITheme
,我需要将其转换为首选类型,而不是使用如下代码:
-
// ThemedForm.cs - class ThemedForm : Form, IThemeable<FormTheme>
private FormTheme _theme;
[DisplayName("Theme")]
[Category("Appearance")]
[Description("The Theme for this form.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(ThemeTypeEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]
public FormTheme Theme
{
get { return _theme; }
set
{
_theme = value;
ChangeTheme();
}
}
答案 0 :(得分:1)
由于ParentTheme
只是ITheme
,因此以下应该可以解决问题:
ParentTheme = (ITheme)Parent.GetType().GetProperty("Theme").GetValue(Parent);