Skip to content

Commit

Permalink
Update winui-multi-window.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Cheesebaron committed Apr 2, 2024
1 parent efb03d5 commit a31fabb
Showing 1 changed file with 36 additions and 9 deletions.
45 changes: 36 additions & 9 deletions docs/_documentation/platform/winui/winui-multi-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,46 @@ title: WinUI Multi-Window View Presenter
category: Platforms
---

We can support multiple windows on the WinUI Platform.
MvvmCross supports multiple windows on the WinUI Platform using the `MvxMultiWindowViewPresenter`, which is the default presenter on WinUI.

- A new attribute has been added MvxNewWindowPresentationAttribute.cs has been added which can be put above views. If detected, the ViewPresenter will open a new window
- All navigate calls that have to support to be executed in a Window other then the main Window have to pass the ViewModel it comes from as the Source. (Note: It is not required that they pass the ViewModel they are coming from, but is the most logical option usually). There are additional methods in the IMvxNavigationService to support this
- An attempt is then made to find the correct window in any of the open windows. If no window is found the mainWindow is used instead
To open a new window your page must inherit from `MvxWindowsPage<TViewModel>` and optionally implement the interface `IMvxNeedWindow`. The interface is used when you need access to the Window itself from the page your are presenting.
Additionally you need to annotate your page with `MvxNewWindowPresentationAttribute`.

- The newly created ViewModel (from the request) is then registered with the Window, so if it wants to call Navigate itself we can find it
```C#
[MvxViewFor(typeof(MyViewModel))]
[MvxNewWindowPresentation]
public sealed partial class MyWindowPage : MvxWindowsPage<MyViewModel>, IMvxNeedWindow
{
public MyWindowPage()
{
InitializeComponent();
}

public void SetWindow(Window window, AppWindow appWindow)
{
// access the Window in this method from `IMvxNeedWindow`
AppWindow = appWindow;
AppWindowUtils.SetTitleBar(appWindow, "Hello new window");
}

public AppWindow AppWindow { get; set; }

- IMvxNeedWindow is used to give the page access to the Window it is in. This allows the page, and by extension the viewmodel via Binding, to set and change the Title and possibly other things. (We only needed it for the title :) )
public bool CanClose()
{
return true;
}
}
```

- If the ViewModel or another service requires direct access to the window, you can use IMvxMultiWindowsService for the IoCContainer. In our case this was used to load the File and Folder selectors in the correct Window
The flow in MvvmCross looks something like this:
- When the attribute `MvxNewWindowPresentationAttribute` is detected by the ViewPresenter, it will attempt to open it in a new Window
- All navigate calls that have to support to be executed in a Window other then the main Window have to pass the ViewModel it comes from, as the Source
- An attempt is then made to find the correct window in any of the open windows. If no window is found the `MainWindow` is used instead
- The newly created ViewModel (from the navigation request) is then registered with the Window, so if it wants to call Navigate itself we can find it
- `IMvxNeedWindow` is used to give the page access to the Window it is in. This allows the page, and by extension the ViewModel via Binding, to set and change the Title and possibly other things on the Window itself
- If the ViewModel or another service requires direct access to the window, you can use `IMvxMultiWindowsService` through the IoCContainer

For example:
For example to show a file picker:

```C#
public FileService(IMvxMultiWindowsService multiWindowsService)
Expand Down Expand Up @@ -48,7 +75,7 @@ private T GetPicker<T>(IMvxViewModel callingViewModel) where T : new()
{
var picker = new T();

Window mainWindow = this._multiWindowsService.GetWindow(callingViewModel);
Window mainWindow = _multiWindowsService.GetWindow(callingViewModel);
IntPtr handle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, handle);

Expand Down

0 comments on commit a31fabb

Please sign in to comment.