I have a Window
class that represent desktop windows, and some of them can be titled via a wrapper (TitledWindow
), and some of them can be on top of others, also via a wrapper (TopWindow
).
Now, I'm trying to create a view-model for a Window
, and I want it to support those three interfaces (IWindow
, ITitledWindow
and ITopWindow
). It looks like this:
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;
}
}
}
This is how I get the view-models:
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();
}
}
The issue is that I can only get the 1st wrapper in the hierarchy.
All the windows in OpenWindows
are also ITopWindow
, but are not ITitledWindow
because it wraps it inside in a private readonly
field (which should probably remain this way).
The only solution I have in mind is to introduce a class that will union them (like TitledTopWindow
) but I'll have to make it for every variation of a window and that's too messy (especially later when I introduce new wrappers to introduce new functionality).
What's the proper way to do it?
Update:
In my searched I've read that you use wrappers to extend functionality, but not to extend the API (which is a goal here).
So if this issue can't be addressed in the way I've intended it to, how can I add functionality in this way?