0

I've added two buttons, with only one visible at a time, to adjust the size of a ContentDialog. I want there to be two sizes: maximum, which would be sized to fill the parent window, or the default "restored" size. It's somewhat similar to standard Windows Maximize and Restore buttons.

I've found that I can use the ContentDialog.Resources with the keys "ContentDialogMaxWidth" and "ContentDialogMaxHeight" in XAML to set one or the other desired sizes, as shown below.

Default size in XAML:

<ContentDialog.Resources>
    <x:Double x:Key="ContentDialogMaxWidth">800</x:Double>
    <x:Double x:Key="ContentDialogMaxHeight">1000</x:Double>
</ContentDialog.Resources>

Maximum size in XAML:

<ContentDialog.Resources>
    <x:Double x:Key="ContentDialogMaxWidth">2000</x:Double>
    <x:Double x:Key="ContentDialogMaxHeight">2000</x:Double>
</ContentDialog.Resources>

However, the above XAML only sets the size once when the ContentDialog opens. I can't seem to change it dynamically after it is opened.

Below are the click events for the two buttons. I've tried to change the two resources shown above dynamically in the events. Even though the resource values are changing (I've tested this), the dialog size does not update.

Is there another way to change the ContentDialog to the desired sizes using the button events?

    private void MaximizeDialogButton_Click(object sender, RoutedEventArgs e)
    {
        this.FullSizeDesired = true;
        this.Resources["ContentDialogMaxWidth"] = 2000;
        this.Resources["ContentDialogMaxHeight"] = 2000;
        this.MaximizeDialogButton.Visibility = Visibility.Collapsed;
        this.RestoreDialogButton.Visibility = Visibility.Visible;
    }

    private void RestoreDialogButton_Click(object sender, RoutedEventArgs e)
    {
        this.FullSizeDesired = false;
        this.Resources["ContentDialogMaxWidth"] = 800;
        this.Resources["ContentDialogMaxHeight"] = 1000;
        this.Width = 800;
        this.Height = 1000;
        this.MaximizeDialogButton.Visibility = Visibility.Visible;
        this.RestoreDialogButton.Visibility = Visibility.Collapsed;
    }
1
  • If I'm going to prototype something, I'm not going to use "resources" or XAML the first time around for a proof of concept. When changing "layout properties (e.g. Width and Height), one typically has to call "UpdateLayout" for a change to take (immediate) effect. If that doesn't work, one can use "another" (same) ContentDialog and "swap" it with the first. Commented Nov 13, 2024 at 18:28

1 Answer 1

1

It seems that ContentDialog doesn't support that. Instead, you can create a custom dialog using the WinUIEx NuGet package.

For example:

WindowDialog.xaml

<ex:WindowEx
    x:Class="WinUIDemoApp.WindowDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:ex="using:WinUIEx"
    xmlns:local="using:WinUIDemoApp"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid RowDefinitions="*,Auto">
        <StackPanel
            Grid.Row="0"
            HorizontalAlignment="Center"
            VerticalAlignment="Center">
            <NumberBox
                x:Name="WidthNumberBox"
                ValueChanged="WidthNumberBox_ValueChanged" />
            <NumberBox
                x:Name="HeightNumberBox"
                ValueChanged="HeightNumberBox_ValueChanged" />
        </StackPanel>
        <Grid
            Grid.Row="1"
            ColumnDefinitions="*,*">
            <Button
                Grid.Column="0"
                Click="OKButton_Click"
                Content="OK" />
            <Button
                Grid.Column="1"
                Click="CancelButton_Click"
                Content="Cancel" />
        </Grid>
    </Grid>

</ex:WindowEx>

WindowDialog.xaml.cs

using Microsoft.UI.Xaml;
using System.Threading.Tasks;
using WinUIEx;

namespace WinUIDemoApp;

public enum WindowDialogResult
{
    Cancel,
    OK,
}

public partial class WindowDialog : WindowEx
{
    private TaskCompletionSource<WindowDialogResult>? _taskCompletionSource;

    public WindowDialog()
    {
        InitializeComponent();
        IsAlwaysOnTop = true;
        this.CenterOnScreen();
    }

    public new object? Content { get; set; }

    public Task<WindowDialogResult> ShowAsync()
    {
        WidthNumberBox.Value = Width;
        HeightNumberBox.Value = Height;

        _taskCompletionSource = new();

        this.Activate();

        return _taskCompletionSource.Task;
    }

    private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        _taskCompletionSource?.SetResult(WindowDialogResult.OK);
        this.Close();
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        _taskCompletionSource?.SetResult(WindowDialogResult.Cancel);
        this.Close();
    }

    private void WidthNumberBox_ValueChanged(Microsoft.UI.Xaml.Controls.NumberBox sender, Microsoft.UI.Xaml.Controls.NumberBoxValueChangedEventArgs args)
    {
        Width = (float)sender.Value;
    }

    private void HeightNumberBox_ValueChanged(Microsoft.UI.Xaml.Controls.NumberBox sender, Microsoft.UI.Xaml.Controls.NumberBoxValueChangedEventArgs args)
    {
        Height = (float)sender.Value;
    }
}

then you can use it like this:

WindowDialog dialog = new();
WindowDialogResult result = await dialog.ShowAsync();
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks @Andrew KeepCoding! I've watched the video linked to GitHub, and it all looks promising. I'll let you know how it goes as soon as I circle back to it.
Even with WinUIEx, I don't see a way to make the window modal, like a content dialog, without creating a custom extension and importing user32.dll. It would have been nice if WinUIEx had controls for disabling title bar buttons, disabling a window, or simply making a window modal--unless I'm just not finding those features.
Never mind my last comment. I figured out a workaround. I added a base window class that inherits WinUIEx. In the base class, I included the ShowAsyn() you had in your answer and disabled the calling parent window using user32.dll's EnableWindow method. Now, all of my modal windows can inherit the base window class I created.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.