Basically what my problem is: I'm trying to display a ContentDialog in my WinUI 3 App.
The command to open the Dialog is triggered by a ContextMenu Button on my "Main Page" (LibraryPage) The content of the Dialog are a bunch of TextBoxes, which i define in another xaml (LibraryAddSongControl)
But I can't directly open the Dialog from my ViewModel because i cannot access the needed XamlRoot from there. And i cannot access the Dialog TextBoxes contents because those lie on the LibraryAddSongViewModel
LibraryPage.xaml
<controls:ListDetailsView
x:Uid="Library"
x:Name="ListDetailsViewControl"
BackButtonBehavior="Manual"
Background="Transparent"
DetailsTemplate="{StaticResource DetailsTemplate}"
ListHeader="Songs"
ItemsSource="{x:Bind ViewModel.AllSongs}"
ItemTemplate="{StaticResource ItemTemplate}"
ListHeaderTemplate="{StaticResource MinimalListHeaderTemplate}"
NoSelectionContentTemplate="{StaticResource NoSelectionContentTemplate}"
SelectedItem="{x:Bind ViewModel.Selected, Mode=TwoWay}"
ViewStateChanged="OnViewStateChanged">
<controls:ListDetailsView.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Add new Song" Icon="Add" Command="{x:Bind ViewModel.AddNewSongCommand}" />
<MenuFlyoutItem Text="Library Statistics" Icon="Help"
Command="{x:Bind ViewModel.ShowLibraryStatisticsCommand}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem Text="Delete Selected" Icon="Delete" Command="{x:Bind ViewModel.DeleteSongCommand}" />
</MenuFlyout>
</controls:ListDetailsView.ContextFlyout>
</controls:ListDetailsView>
LibraryAddSongControl.xaml
<UserControl
x:Class="Maestro.Views.Dialogs.LibraryAddSongControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Maestro.Views.Dialogs"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:extensions="using:CommunityToolkit.WinUI.UI"
mc:Ignorable="d">
<Grid>
<StackPanel>
<TextBox Header="Titel" Text="{x:Bind ViewModel.Title, Mode=TwoWay}"/>
<TextBox Header="Beschreibung" Text="{x:Bind ViewModel.Description, Mode=TwoWay}"/>
<TextBox Header="Album" Text="{x:Bind ViewModel.Album, Mode=TwoWay}"/>
<TextBox Header="Artist(s)" Text="{x:Bind ViewModel.Artists, Mode=TwoWay}"/>
<TextBox Header="Dauer" Text="{x:Bind ViewModel.Duration, Mode=TwoWay}" extensions:TextBoxExtensions.Mask="99:99" />
<TextBox Header="URL" Text="{x:Bind ViewModel.Url, Mode=TwoWay}"/>
<!--<TextBox Header="Titel" Text="{x:Bind ViewModel.ThumbnailPath, Mode=TwoWay}"/>-->
</StackPanel>
</Grid>
</UserControl>
The ContextMenu command to open the ContentDialog from the LibraryViewModel
[RelayCommand]
public async Task AddNewSong()
{
ContentDialog dialog = new();
dialog.XamlRoot = //Not accessible from ViewModel!
dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
dialog.Title = "Add a new Song to the Library";
dialog.PrimaryButtonText = "Add";
dialog.CloseButtonText = "Cancel";
dialog.IsSecondaryButtonEnabled = false;
dialog.DefaultButton = ContentDialogButton.Primary;
dialog.Content = App.GetService<LibraryAddSongControl>();
ContentDialogResult result = await dialog.ShowAsync();
if (result == ContentDialogResult.Primary)
{
//Logic to handle Save command from Dialog
}
}
Logic in the LibraryAddSongViewModel that gets the contents of the Textboxes and saves them in an sqlite DB
public void AddSong()
{
SqliteHelper.AddSong(new Song
{
SongTitle = Title,
SongDescription = Description,
SongAlbum = Album,
SongArtists = [$"{Artists}"],
SongDuration = (60 * Convert.ToInt32(Duration.Substring(0, 2)) + Convert.ToInt32(Duration.Substring(3, 2))),
SongURL = Url,
});
}
I tried to call the AddSong method of LibraryAddSongViewModel from the LibraryViewModel, but that resulted in the ViewModel properties that are bound to the Tedtbox contents to be empty, and not getting updated whenever i type something in the textbox
My ultimate question is, what is a clean MVVM-style solution to displaying a dialog from Xaml1, when the dialog itself also has Elements like Textboxes that have values which need to be processed (in my case, just saving them to a database)
ListDetailsViewControl.XamlRoot?