于是,经过基于上述回答一些调查研究,进一步搜索谷歌,并要求谁知道一些关于同事C#我选择的解决问题的方法如下。我仍然对评论,建议和改进感兴趣。
首先关于这个问题,这实际上是在这个意义上,GUI被控制的东西非常通用,即必须保持完全抽象的,通过一系列以它的响应GUI必须作出反应事件的一些进一步的细节。有几个不同的问题:
- 事件本身,具有不同的数据类型。随着程序的发展,事件将被添加,删除和更改。
- 如何桥接几个组成GUI的类(不同的UserControls)和抽象硬件的类。
- 所有类都可以产生并消耗事件,并且必须尽可能地解耦。
- 编译器应发现尽可能(例如发送一个数据类型的事件,但一个期望另一个comsumer)编码cockups
的这个第一部分是所述事件。由于GUI和设备可以引发多个事件,可能具有与它们相关的不同数据类型,因此事件调度程序非常方便。这必须是在这两个事件和数据通用的,所以:
// Define a type independent class to contain event data
public class EventArgs<T> : EventArgs
{
public EventArgs(T value)
{
m_value = value;
}
private T m_value;
public T Value
{
get { return m_value; }
}
}
// Create a type independent event handler to maintain a list of events.
public static class EventDispatcher<TEvent> where TEvent : new()
{
static Dictionary<TEvent, EventHandler> Events = new Dictionary<TEvent, EventHandler>();
// Add a new event to the list of events.
static public void CreateEvent(TEvent Event)
{
Events.Add(Event, new EventHandler((s, e) =>
{
// Insert possible default action here, done every time the event is fired.
}));
}
// Add a subscriber to the given event, the Handler will be called when the event is triggered.
static public void Subscribe(TEvent Event, EventHandler Handler)
{
Events[Event] += Handler;
}
// Trigger the event. Call all handlers of this event.
static public void Fire(TEvent Event, object sender, EventArgs Data)
{
if (Events[Event] != null)
Events[Event](sender, Data);
}
}
现在我们需要一些事件,并从C世界的到来,我想枚举,所以我定义了一些事件,该GUI将提高:
public enum DEVICE_ACTION_REQUEST
{
LoadStuffFromXMLFile,
StoreStuffToDevice,
VerifyStuffOnDevice,
etc
}
现在静态类此事件中,可以定义新的调度程序的范围(命名空间,典型值)以内的任何地方:
public void Initialize()
{
foreach (DEVICE_ACTION_REQUEST Action in Enum.GetValues(typeof(DEVICE_ACTION_REQUEST)))
EventDispatcher<DEVICE_ACTION_REQUEST>.CreateEvent(Action);
}
这为在连接每个事件的事件处理程序嗯。
并通过订阅这样的代码在消费设备对象的构造函数的事件消耗:
public DeviceController()
{
EventDispatcher<DEVICE_ACTION_REQUEST>.Subscribe(DEVICE_ACTION_REQUEST.LoadAxisDefaults, (s, e) =>
{
InControlThread.Invoke(this,() =>
{
ReadConfigXML(s, (EventArgs<string>)e);
});
});
}
凡InControlThread.Invoke是,仅包装invoke调用一个抽象类。
活动可以通过GUI简单地提出:
private void buttonLoad_Click(object sender, EventArgs e)
{
string Filename = @"c:\test.xml";
EventDispatcher<DEVICE_ACTION_REQUEST>.Fire(DEVICE_ACTION_REQUEST.LoadStuffFromXMLFile, sender, new EventArgs<string>(Filename));
}
这样做应该事件提高和消费类型不匹配(在此字符串文件名),编译器会抱怨的优势。
有许多增强功能可以做,但这是问题的严重性。正如我在评论中所说,我会感兴趣,特别是如果有任何明显的疏漏/缺陷或缺陷。希望这可以帮助某人。
这可能是最简单的方法,它在一开始就运行良好,之前我已经使用过,但它的缺点是一旦GUI变得更大并且由更多类或UserControl组成(它不可避免地似乎发生)它不能很好地扩展。 也许我应该在我的问题中指出,我寻找一个通用解决方案的原因是我完全期望这个应用程序随着时间的推移而增长,并希望能够扩展。 – 0xDEADBEEF 2010-04-13 09:12:47