In the existing Telerik RadControls there is no way to programmatically set the window a RadWindow appears in. They always appear in the Main Window. This is an issue for Silverlight 5 Out-of-Browser (OOB) applications making use of multiple windows.
Please introduce a SetWindow function on WindowBase so that the Window the RadWindow appears in can be set. As per the new Silverlight 5 Popup.SetWindow instance method.
For example the following should be possible:
var rw =
new
RadWindow();
rw.SetWindow(Window.GetWindow(
this
));
rw.Content =
new
TextBlock { Text =
"My Content"
};
rw.ShowDialog();
The value passed to the SetWindow function should be used to determine the RootVisual of the RadWindow using Silverlight 5's new Window.GetWindow static method. It should also be used to set the window of any Popup controls related to the RadWindow.
Alternatively at the very least please honour the Owner property in a multi-window environment.
The following steps describe how this can be achieved against the 2011_3_1220 Silverlight RadControls source:
Solution: Navigation_SL
Project: Controls_SL
Files: WindowBase.cs, WindowHostFactory.cs, MultiplePopupWindowHost.cs
File: Window/WindowBase.cs
Add a window field which defaults to the main window:
private
System.Windows.Window _window = System.Windows.Application.Current.MainWindow;
Add a public SetWindow method (with comments):
public
void
SetWindow(System.Windows.Window window)
{
_window = window;
}
Edit the ShowWindow method to additionally pass the _window field:
this
.host = WindowHostFactory.GetWindowHost(
this
, _window);
File: Window/InternalWindow/WindowHostFactory.cs
Edit the GetWindowHost method, adding a windowWindow argument and call CreateHost with it:
public
static
IWindowHost GetWindowHost(WindowBase window, System.Windows.Window windowWindow)
{
var windowHost = CreateHost(windowWindow);
windowHost.Setup(window);
return
windowHost;
}
Edit the CreateHost method, adding a window argument and use it to construct the MultiplePopupWindowHost instance:
private
static
IWindowHost CreateHost(System.Windows.Window window)
return
new
MultiplePopupWindowHost(window);
File: Window/InternalWindow/MultiplePopupWindowHost.cs
Add a window field:
private
System.Windows.Window _window;
Add a constructor to take the window as an argument:
public
MultiplePopupWindowHost(System.Windows.Window window)
{
_window = window;
}
Edit the GetHostManager method to use the window field:
protected
override
PopupHostManagerBase GetHostManager()
{
if
(
this
.manager ==
null
)
{
var owner = FindRootOwner(
this
.DragableWindow);
// Fix begin
FrameworkElement root;
if
(owner ==
null
)
{
root = _window.Content;
}
else
{
root = ApplicationHelper.GetRootVisual(owner);
}
// Fix end
//var root = ApplicationHelper.GetRootVisual(owner);
this
.manager =
new
PopupHostManager(root);
}
return
this
.manager;
}
Edit the constructor to call SetWindow on the popup:
public
PopupHostManager(FrameworkElement root)
:
base
(root)
{
this
.popup =
new
System.Windows.Controls.Primitives.Popup
{
Child =
this
.Host =
new
Canvas()
};
this
.popup.SetWindow(Window.GetWindow(root));
if
(root ==
null
)
{
this
.popup.Opened +=
this
.OnPopupOpened;
}
this
.popup.IsOpen =
true
;
}
File: Window/RadWindow.cs
When the Owner property value is set so should the window be set:
private ContentControl _owner = null;
/// <
summary
>
/// Gets or sets the Owner of the RadWindow.This is a dependency property.ull
/// </
summary
>
public ContentControl Owner
{
get { return _owner; }
set
{
_owner = value;
this.SetWindow(Window.GetWindow(_owner) ?? Application.Current.MainWindow);
}
}
File: Window/InternalWindow/BrowserWindowPresenter.cs
Method: UpdateStartupLocation
Finally with multiple windows now supported the behaviour of the WindowStartupLocation property when set to CenterScreen needs to be defined. I suggest that it defaults to the center of it's owner's window (rather than appear in a secondary window with the center position from the main window), i.e.:
if (centerScreen)
{
#if SILVERLIGHT
var window = Window.GetWindow(this);
var plugin =
window == null
? Application.Current.MainWindow.Content as FrameworkElement
: window.Content;
var size =
new Size(plugin.ActualWidth / ApplicationHelper.ZoomFactor,
plugin.ActualHeight / ApplicationHelper.ZoomFactor);
#else
var size = ApplicationHelper.ApplicationSize;
#endif
location.X = Math.Floor((size.Width - presenterSize.Width) / 2);
location.Y = Math.Floor((size.Height - presenterSize.Height) / 2);
this.UpdatePresenterPosition(location.X, location.Y);
}