1

I have problem with a WelcomeScreen developed in WinUI 3. In resolution (1920 * 1080), Scale (125%), the controls on the window are displayed correctly, but they are invisible when in resolution (1920 * 1080), Scale (150%). Is there any way I can get the needed size of the window after scaling and adjust the windows size dynamically? Thanks.

// this window size works with scaling 125% but not work with 150%
this.AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(0, 0, 1200, 665));

WelcomeScreen.xaml:

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Name="WelcomeScreenWindow"
    x:Class="Views.WelcomeScreen.WelcomeScreen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Views.WelcomeScreen"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="">

    <Grid ColumnDefinitions="*,*,*" RowDefinitions="*" >
        <StackPanel Grid.Column="0" Grid.ColumnSpan="3" Orientation="Vertical"  >
            <local:WelcomeScreenPage1 x:Name="WelcomeScreenPage1"/>
            <local:WelcomeScreenPage2 x:Name="WelcomeScreenPage2"/>
            <local:WelcomeScreenPage3 x:Name="WelcomeScreenPage3"/>
            <Line Stroke="LightGray" X1="0" Y1="0" X2="1200" Y2="0" StrokeThickness="2" Margin="12,0,12,0"/>
            <RelativePanel>
                <CheckBox x:Name="DoNotShowAaginCheckBox" x:Uid="DoNotShowThisAgain" FontFamily="{StaticResource VeneerFont}" IsChecked="{x:Bind WelcomeScreenPageViewModel.IsDisplayAgain, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="12,12,0,0"  VerticalContentAlignment="Center" />
                <Button x:Name="BackButton" Width="100" Style="{StaticResource AccentButtonStyle}" FontFamily="{StaticResource VeneerFont}" Command="{x:Bind WelcomeScreenPageViewModel.BackCommand}" RelativePanel.LeftOf="PipsPager" Content="{x:Bind WelcomeScreenPageViewModel.BackButtonText, Mode=OneWay}" Margin="12,12,12,0"/>
                <PipsPager x:Name="PipsPager" Margin="0,15,0,0" NumberOfPages="3" SelectedPageIndex="{x:Bind WelcomeScreenPageViewModel.CurrentPageIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" RelativePanel.AlignHorizontalCenterWithPanel="True" />
                <Button x:Name="NextButton" Width="100" Style="{StaticResource AccentButtonStyle}" FontFamily="{StaticResource VeneerFont}" Command="{x:Bind WelcomeScreenPageViewModel.NextCommand}" Content="{x:Bind WelcomeScreenPageViewModel.NextButtonText,Mode=OneWay}" RelativePanel.RightOf="PipsPager" Margin="12,12,12,0"/>
            </RelativePanel>
        </StackPanel>
    </Grid>
</Window>

WelcomeScreen.xaml.cs:

using Microsoft.UI.Windowing;
using Microsoft.UI;
using Microsoft.UI.Xaml;
using ViewModels.WelcomeScreen;

using System.ComponentModel;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace Views.WelcomeScreen
{
    /// <summary>
    /// An empty window that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class WelcomeScreen : Window
    {
        public WelcomeScreenPageViewModel WelcomeScreenPageViewModel { get; }

        public void GetAppWindowAndPresenter()
        {
            var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
            WindowId myWndId = Win32Interop.GetWindowIdFromWindow(hWnd);
            _apw = AppWindow.GetFromWindowId(myWndId);
            _presenter = _apw.Presenter as OverlappedPresenter;
        }

        private AppWindow _apw;
        private OverlappedPresenter _presenter;

        private void InitializeControls()
        {
            GetAppWindowAndPresenter();
            _presenter.IsResizable = false;
            _presenter.IsMaximizable = false;
            _presenter.IsMinimizable = false;
            _apw.TitleBar.IconShowOptions = IconShowOptions.HideIconAndSystemMenu;
            _apw.SetIcon("Assets/Apple.ico");
        }

        public WelcomeScreen(WelcomeScreenPageViewModel welcomeScreenPageViewModel)
        {
            this.InitializeComponent();
            this.InitializeControls();

            // this window size works with scaling 125% but not work with 150%
            this.AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(0, 0, 1200, 665));

            WelcomeScreenPageViewModel = welcomeScreenPageViewModel;
         
            UpdateNavigationFrame(0);

            WelcomeScreenPageViewModel.PropertyChanged += ProcessPropertyChanged;

            WelcomeScreenPageViewModel.ClosingRequest += (sender, e) => this.Close();
        }

        private void ProcessPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == (nameof(WelcomeScreenPageViewModel.CurrentPageIndex)))
                UpdateNavigationFrame(WelcomeScreenPageViewModel.CurrentPageIndex);
        }

        private void UpdateNavigationFrame(int index)
        {
            WelcomeScreenPage1.Visibility = Visibility.Collapsed;
            WelcomeScreenPage2.Visibility = Visibility.Collapsed;
            WelcomeScreenPage3.Visibility = Visibility.Collapsed;

            if (index == 0)
                WelcomeScreenPage1.Visibility = Visibility.Visible;

            if (index == 1)
                WelcomeScreenPage2.Visibility = Visibility.Visible;

            if (index == 2)
                WelcomeScreenPage3.Visibility = Visibility.Visible;
        }
    }
}

In resolution (1920*1080), Scale (125%):

enter image description here

In resolution (1920*1080), Scale (150%):

enter image description here

Scaling settings:

enter image description here

2
  • Did I understand you right? You want to change system settings, screen size in pixels and scaling, while the application is running and want the application to adjust right away, right? Commented Feb 25 at 2:21
  • @SergeyAKryukov Thanks. Actually when the welcome screen is running and the application adjusts right away, the problem is when shut it down and restart the welcome screen, the controls become invisible. Commented Feb 25 at 7:27

1 Answer 1

1

You can get notified when the DPI changes. Instead of implementing all by yourself, I recommend using the WinUIEx NuGet package.

  1. Install the WinUIEx NuGet package.
  2. Replace Window with WindowEx:
    using WinUIEx;
    
    namespace WinUIDemoApp;
    
    public sealed partial class MainWindow : WindowEx
     {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
    
    <winex:WindowEx
        xmlns:winex="using:WinUIEx"
        x:Class="WinUIDemoApp.MainWindow"
        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:local="using:WinUIDemoApp"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        ...
    </winex:WindowEx>
    
  3. Then in App.xaml.cs, listen to WM_DPICHANGED:
    private WindowEx? Window { get; set; }
    
    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        Window = new MainWindow();
        var windowManager = WindowManager.Get(Window);
        windowManager.WindowMessageReceived += WindowManager_WindowMessageReceived;
        Window.Activate();
    }
    
    private void WindowManager_WindowMessageReceived(object? sender, WinUIEx.Messaging.WindowMessageEventArgs e)
    {
        if (e.Message.MessageId != 0x02E0)  // WM_DPICHANGED
        {
            return;
        }
    
        var dpi = Window.GetDpiForWindow();
        System.Diagnostics.Debug.WriteLine($"DPI: {dpi}");
        // Resize your window here...
    }
    
Sign up to request clarification or add additional context in comments.

Comments

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.