我想创建课程UserAction
。该类接受一组小部件和一个回调。主要思想是有一个共同的对象,你可以在其中启用或禁用各种小部件(或可见/不可见)。
例如,对于 saveAction ,类UserAction
的对象,您要添加 opSave (ToolStripMenuItem
)和< em> tbbSave (a ToolStripButton
)。
this.saveAction = new UserAction( this.OnSave );
this.saveAction.AddControl( this.opSave );
this.loadAction.AddControl( this.tbbSave );
当您将saveAction
的已启用属性设置为false
...
saveAction.Enabled = false;
saveAction应该在集合的所有控件上运行,并将所有Enabled
属性设置为 false 。
问题是Control
,最初似乎是最常见的根类,包括已启用和可见,但遗憾的是它不是根ToolStrip-whatever
类的类。公共类是Component
。它不包括那些属性。
我写的(丑陋的)代码是:
class UserAction {
// ...
public void SetControlsEnabled(bool value)
{
foreach(Component cmp in this.controls) {
var c = cmp as Control;
var tsi = cmp as ToolStripItem;
if ( c != null ) {
c.Enabled = value;
}
else
if ( tsi != null ) {
tsi.Enabled = value;
}
}
return;
}
public bool Enabled {
// ...
set {
this.SetControlsEnabled( value );
}
}
// ...
private List<Component> components;
}
用于访问 Enabled 属性的代码对于两种情况都是相同的,但遗憾的是没有定义属性 Enabled 和的公共类或接口可见。或者,至少,我一直无法找到它。
上面的代码解决了ToolStrip-whatever
组件和按钮等问题...遗憾的是,旧样式菜单和工具栏按钮未被覆盖,我必须检查Menu
和ToolBarButton
具体(同样,共同的祖先是Component
,但该类没有定义这些属性。)
是否有更清洁和通用的解决方案?
答案 0 :(得分:1)
只需添加一个抽象级别。这将消除丑陋的代码并真正使它变得更好。
class UserAction
{
public void SetControlsEnabled(bool value)
{
foreach (ISupportEnabled component in this.components)
{
component.Enabled = value;
}
}
public bool Enabled
{
// ...
set
{
this.SetControlsEnabled(value);
}
}
private List<ISupportEnabled> components = new List<ISupportEnabled>();
public void AddComponent(ISupportEnabled component)
{
if (!components.Contains(component))
{
components.Add(component);
}
}
}
public interface ISupportEnabled
{
bool Enabled { get; set; }
}
private class ControlAdapter : ISupportEnabled
{
private readonly Control control;
public ControlAdapter(Control control)
{
this.control = control;
}
public bool Enabled
{
get { return control.Enabled; }
set { control.Enabled = value; }
}
}
private class ToolStripItemAdapter : ISupportEnabled
{
private readonly ToolStripItem toolStripItem;
public ToolStripItemAdapter(ToolStripItem toolStripItem)
{
this.toolStripItem = toolStripItem;
}
public bool Enabled
{
get { return toolStripItem.Enabled; }
set { toolStripItem.Enabled = value; }
}
}
然后将其用作
UserAction userAction = new UserAction();
userAction.AddComponent(new ControlAdapter(this.MyTextBox));
userAction.AddComponent(new ToolStripItemAdapter(this.MyToolStripItem));
否则代码中的位置:
userAction.Enabled = false;
我希望你有这个想法,如果需要以这种方式使用更多的类,你需要为它创建一个新的适配器。如果您希望隐藏适配器创建代码,可以创建一个工厂来检查对象的类型并为其返回适配器。
答案 1 :(得分:1)
正如已经建议的那样:
foreach(dynamic cmp in this.controls)
{
cmp.Enabled = value;
}