我有一个代表桌面窗口的Window
类,其中一些可以通过包装器(TitledWindow
)命名,其中一些可以在其他窗口之上,也可以通过包装器(TopWindow
)。
现在,我正在尝试为Window
创建一个视图模型,我希望它支持这三个接口(IWindow
,ITitledWindow
和ITopWindow
)。它看起来像这样:
public class WindowViewModel : ITopWindow, ITitledWindow
{
private readonly IWindow _window;
public WindowViewModel(IWindow window)
{
_window = window;
}
public IntPtr Handle
{
get { return _window.Handle; }
}
public Boolean? IsTopmost
{
get
{
var thisTopWindow = _window as ITopWindow;
if (thisTopWindow == null)
return null;
return thisTopWindow.IsTopmost;
}
set
{
var thisTopWindow = _window as ITopWindow;
if (thisTopWindow != null)
thisTopWindow.IsTopmost = value;
}
}
public String Title
{
get
{
var thisTitledWindow = _window as ITitledWindow;
return thisTitledWindow == null ? null : thisTitledWindow.Title;
}
}
}
这就是我获取视图模型的方法:
public IList<WindowViewModel> OpenWindows
{
get
{
var windowViewModels =
from window in _windowEnumerator.EnumerateWindows()
let titledWindow = new TitledWindow(window, _windowTitleReader)
let topWindow = new TopWindow(titledWindow, _topmostManager)
select new WindowViewModel(topWindow);
return windowViewModels.ToList();
}
}
问题是我只能在层次结构中获得1 st 包装。
OpenWindows
中的所有窗口也都是ITopWindow
,但不是ITitledWindow
,因为它将其包含在private readonly
字段中(可能应该保持这种方式)。
我想到的唯一解决方案是引入一个将它们联合起来的类(如TitledTopWindow
),但是我必须为窗口的每个变体制作它并且太乱了(特别是后来当我引入新包装器来引入新功能。)
这样做的正确方法是什么?
更新:
在我的搜索中,我已经读过您使用包装器来扩展功能,但不是为了扩展API(这是一个目标)。
因此,如果无法按照我的预期方式解决此问题,我该如何以这种方式添加功能?
答案 0 :(得分:2)
我的建议与
有关 class Window
{
List<object> traits;
T GetTrait<T>()
{
return traits.Where(t => t.GetType() == typeof(T)).FirstOrDefault();
}
}
Window w;
var topLevel = w.GetTrait<TopLevel>();
if (topLevel != null)....
但是这个建议需要认真重新修改接口/代码。
我认为你真的想要跟随无效代码,所以你可以添加任意数量的包装器,并且仍然允许所有接口在最终类中可见:
class TopLevel<T> : T where T:Window
我认为你无法直接实现这一点(因为你无法从其模板参数中派生出模板类)。
一种方法是在运行时生成派生类,添加必要的接口并代理内部类实现的所有接口。在Dynamically creating a proxy class中讨论/链接的可能方法(即此A simple Dynamic Proxy)。