Reputation: 111
I tried Window.Activate(), but that does not appear to bring up the specific window, just the app itself.
I have multiple windows that the app is managing, and I want to be able to bring up a specific window on demand.
Upvotes: 1
Views: 647
Reputation: 5276
I am sorry for overshooting the two hours with 2 days but as promised below is your solution. It might not be the ideal way of achieving such a functionality but in my opinion it's a solution that works perfectly. I've uploaded a solution as well to one drive.
To actually handle multiple window switching without relaunching a new window rather in your words:
bring up a specific window on demand.
What you need is a window logging service. What this service would do is, each time it opens up a new window, it logs it along with the type of window opened. I've kept a neat enum
to manage the windows that open.
I'll talk more about the window logging service more than the UI part as the UI is just basic buttons calling the service.
windowLauncherService
WindowIDs
and TypeOfWindow
launched.HandleWindowSwitch
method, check if the window has already been launched (check if it exists in the private Dictionary), if it does simply call await ApplicationViewSwitcher.TryShowAsStandaloneAsync(Convert.ToInt32(existingViewID));
. Where you get the existingViewID from the key of the dictionary.That's it. Below is my WindowServiceCode:
namespace MultipleWindowTracker.Services
{
internal class WindowLauncherService
{
public static WindowLauncherService Instance { get; } = new WindowLauncherService();
private Dictionary<int, WindowType> WindowLogs { get; set; }
internal async void HandleWindowSwitch(WindowType typeOfWindow)
{
if (WindowLogs?.ContainsValue(typeOfWindow) == true)
{
var existingViewID = WindowLogs?.FirstOrDefault(x => x.Value == typeOfWindow).Key;
if (existingViewID != null)
{
await ApplicationViewSwitcher.TryShowAsStandaloneAsync(Convert.ToInt32(existingViewID));
}
else
{
//Handle Error Here!
}
}
else
{
await OpenNewWindow(typeOfWindow);
}
}
/// <summary>
/// Logs the new window.
/// </summary>
/// <param name="WindowID">The window identifier.</param>
/// <param name="typeOfWindow">The type of window.</param>
private void LogNewWindow(int WindowID, WindowType typeOfWindow)
{
if (WindowLogs?.ContainsKey(WindowID) == true)
return;
if (WindowLogs == null)
WindowLogs = new Dictionary<int, WindowType>();
WindowLogs.Add(WindowID, typeOfWindow);
}
/// <summary>
/// Opens the new window and if success logs it.
/// </summary>
/// <param name="typeOfWindow">The type of window.</param>
/// <returns></returns>
private async Task OpenNewWindow(WindowType typeOfWindow)
{
Type windowToLaunch = null;
switch (typeOfWindow)
{
case WindowType.Main:
windowToLaunch = typeof(MainPage);
break;
case WindowType.First:
windowToLaunch = typeof(Scenarios.FirstWindow);
break;
case WindowType.Second:
windowToLaunch = typeof(Scenarios.SecondWindow);
break;
case WindowType.Third:
windowToLaunch = typeof(Scenarios.ThridWindow);
break;
default:
return;
}
CoreApplicationView newView = CoreApplication.CreateNewView();
var currentFrame = Window.Current.Content as Frame;
if (currentFrame.Content is MainPage)
{
var mainFrameID = ApplicationView.GetForCurrentView().Id;
LogNewWindow(mainFrameID, WindowType.Main);
}
int newViewId = 0;
await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame frame = new Frame();
frame.Navigate(windowToLaunch, null);
Window.Current.Content = frame;
// You have to activate the window in order to show it later.
Window.Current.Activate();
newViewId = ApplicationView.GetForCurrentView().Id;
});
bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
if (viewShown)
{
LogNewWindow(newViewId, typeOfWindow);
}
else
{
//handle error on launch here!
}
}
}
public enum WindowType
{
Main,
First,
Second,
Third
}
}
And on button click this is what you do:
private void HandleWindowChange(object sender, RoutedEventArgs e)
{
var s = sender as Button;
var conversionSuccessful = Enum.TryParse((string)s.Tag, true, out Services.WindowType TypeOfWindow);
if (conversionSuccessful)
{
Services.WindowLauncherService.Instance.HandleWindowSwitch(TypeOfWindow);
}
}
Please Note: All Buttons in all views have the same click event code and they all call the same singleton instance.
Refer to my source code from one drive. For any help do let me know in the comments section. Please note I am using VS2017, if you're using older versions, few things might not be available for eg: the out
keyword in Enum.TryParse<>
The Link to the complete solution on github
Upvotes: 1