Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: default project improvements #10388

Open
sonnemaf opened this issue Feb 26, 2025 · 6 comments
Open

Proposal: default project improvements #10388

sonnemaf opened this issue Feb 26, 2025 · 6 comments
Labels
feature proposal New feature proposal needs-triage Issue needs to be triaged by the area owners

Comments

@sonnemaf
Copy link
Contributor

sonnemaf commented Feb 26, 2025

Proposal: default project improvements

Summary

The current project template for a WinUI3 app is lacking a lot of issues. I recently created a new project which I wanted to use for a demo. It is strange that I had to add so many things before I could use it. These should be out of the box.

In this proposal I will show all the things I think are missing or wrong in the current template.

Scope

Capability Priority
Visual Assets - Place the Visual Assets in a Tiles subfolder folder of the Assets folder Must
Visual Assets - Remove unused tiles Must
Visual Assets - Add an Icon.ico and set it on the Window Must
MainWindow - Add MicaBackdrop Must
MainWindow - Add the new TitleBar Must
MainWindow - Add a Minimum size Must
MainWindow - Replace the 'Click Me' Button for a Frame and navigate to a MainPage Must
Introduce a MainPage with a Counter Should
Folders - Add a GlobalUsings.cs Could
Folders - Introduce a Views folder Could
Folders - Default Styles.xaml Resource Dictionary Should
Folders - Default Themes.xaml Resource Dictionary Should
  • 'Must' implies that the feature should not ship without this capability.
  • 'Should' is something we should push hard for, but is not absolutely required to ship.
  • 'Could' is a nice-to-have; a good stretch goal that isn't painful if we don't achieve it.
  • 'Won't' is a clear statement that the proposal/feature will intentionally not have that capability.

Visual Assets

Place the Visual Assets in a Tiles subfolder folder of the Assets folder

Currently all tiles are placed in the Assets folder itself. I often create extra folders too like Fonts, Sounds, Images but they don't have to be there in the template.

The Package.appxmanifest should point to this folder.

Image

Remove unused tiles

The Wide310x150Logo.png and SplashScreen.png can be removed from the project. They are not used in WinUI.

Add an Icon.ico and set it on the Window

A WinUI3 should have an Icon file otherwise the app will get a blue background color in the TaskBar. It took me hours to find a solution for it. Thanks to many on the Discord group.

In the Assets/Tiles folder I would like to have an Icon.ico file with the Build Action set to Content. In the 'App.xaml.cs' file you need to call SetIcon().

For this demo I converted a Smiley.png into an Icon file using the `Simple Icon File Maker' app from Joe Finney.

/// <summary>
/// Invoked when the application is launched.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    m_window = new MainWindow();

    AppWindow appWindow = GetAppWindow(m_window);
    appWindow.SetIcon("Assets/Tiles/Icon.ico");

    // This requires WinUIEx NuGet Package
    // m_window.SetIcon("Assets/Icons/Icon.ico");

    m_window.Activate();

}

private static AppWindow GetAppWindow(Window window) {
    IntPtr hWnd = WindowNative.GetWindowHandle(window);
    WindowId wndId = Win32Interop.GetWindowIdFromWindow(hWnd);
    return AppWindow.GetFromWindowId(wndId);
}

Image

MainWindow

Add MicaBackdrop

<Window
    x:Class="App127.Views.Windows.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:App127"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:pages="using:App127.Views.Pages"
    mc:Ignorable="d">
    <Window.SystemBackdrop>
        <MicaBackdrop />
    </Window.SystemBackdrop>
    <Grid>

The ugly white background is now gone. And you have Mica.

Image

Add the new TitleBar

If you are using WinAppSDK version 1.7 (currently in preview) you could use the new TitleBar control in your Window

<?xml version="1.0" encoding="utf-8" ?>
<Window
    x:Class="App106.Views.Windows.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:App106"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:pages="using:App106.Views.Pages"
    mc:Ignorable="d">
    <Window.SystemBackdrop>
        <MicaBackdrop />
    </Window.SystemBackdrop>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <TitleBar Title="{x:Bind Title}" Background="{ThemeResource SystemAccentColor}">
            <TitleBar.IconSource>
                <ImageIconSource ImageSource="/Assets/Tiles/StoreLogo.png" />
            </TitleBar.IconSource>
        </TitleBar>

The Title of the TitleBar is databound to the Title property of the window. The IconSource is set to the StoreLogo.png.

You also have to set the ExtendsContentIntoTitleBar and the Title, so I changed the constructor of the MainWindow into this. Using the Package.DisplayName is better than using some hard coded string.

public sealed partial class MainWindow : Window {
    public MainWindow() {
        this.InitializeComponent();

        Title = global::Windows.ApplicationModel.Package.Current.DisplayName;
        ExtendsContentIntoTitleBar = true;
    }
}

Add a Minimum size

Add a solution to the MainWindow to set the minimum size. Nobody wants this.

Image

Replace the 'Click Me' Button for a Frame and navigate to a MainPage

I think the currently used 'Click Me' button is quite useless. I think you should not have any XAML controls in a Window. Windows are limited. They cannot have Resources. In UWP apps we are used to write XAML in Pages, by default a MainPage.xaml. That is what we should do in WinUI too. We can also use the BackButton logic of the TitleBar to make that easier too.

<?xml version="1.0" encoding="utf-8" ?>
<Window
    x:Class="App106.Views.Windows.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:App106"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:pages="using:App106.Views.Pages"
    mc:Ignorable="d">
    <Window.SystemBackdrop>
        <MicaBackdrop />
    </Window.SystemBackdrop>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <TitleBar
            Title="{x:Bind Title}"
            BackRequested="TitleBar_BackRequested"
            Background="{ThemeResource SystemAccentColor}"
            IsBackButtonEnabled="True"
            IsBackButtonVisible="{x:Bind RootFrame.CanGoBack, Mode=OneWay}">
            <TitleBar.IconSource>
                <ImageIconSource ImageSource="/Assets/Tiles/StoreLogo.png" />
            </TitleBar.IconSource>
        </TitleBar>
        <Frame x:Name="RootFrame" Grid.Row="1">
            <Frame.ContentTransitions>
                <TransitionCollection>
                    <EntranceThemeTransition />
                </TransitionCollection>
            </Frame.ContentTransitions>
        </Frame>
    </Grid>
</Window>

In the constructor of the MainWindow you can navigate to a MainPage and also have the BackRequested handler.

public sealed partial class MainWindow : Window {
    public MainWindow() {
        this.InitializeComponent();

        Title = global::Windows.ApplicationModel.Package.Current.DisplayName;
        ExtendsContentIntoTitleBar = true;

        RootFrame.Navigate(typeof(MainPage));
    }

    private void TitleBar_BackRequested(TitleBar sender, object args) {
        if (RootFrame.CanGoBack) {
            RootFrame.GoBack();
        }
    }
}

This results in a Back button in the TitleBar if back navigation is possible.

Image

Introduce a MainPage with a Counter

We need a MainPage and it needs something more than only a Click Me button. In Blazor and Maui there is a Counter page. Maybe we should implement that too.

Folders

Add a GlobalUsings.cs

We don't have ImplicitUsings for WinUI apps like ASP.NET, WPF or Windows Forms. Let's create a GlobalUsings.cs file to mimic this behavior.

global using Microsoft.UI.Xaml;
global using Microsoft.UI.Xaml.Controls;
global using Microsoft.UI.Xaml.Controls.Primitives;

global using Windows.System;

Introduce a Views folder

All view related items (Windows, Pages, Resources, Controls, Dialogs) should be placed in a Views folder. Preferably with subfolders for each type.

Image

Default Styles.xaml Resource Dictionary

The project could have a Styles.xaml resource dictionary which is merged from the App.xaml file. Having a separate file for it learns unexperienced developers to use styling and the use of Resource Dictionaries.

Image

Default Themes.xaml Resource Dictionary

Add a Themes.xaml resource dictionary and reference it from the App.xaml. If new developers know that this exists, they will start using it (hopefully).

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App106.Views.Resources">
    <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary x:Key="Default">
            <!--  Dark Resources  -->
        </ResourceDictionary>
        <ResourceDictionary x:Key="Light">
            <!--  Dark Resources  -->
        </ResourceDictionary>
        <ResourceDictionary x:Key="HighContrast">
            <!--  High Contrast Resources  -->
        </ResourceDictionary>
    </ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

Important Notes

I'm quite sure that there are many other improvements to be made. Is my priority ok? Please react on this proposal to get them all discussed.

@sonnemaf sonnemaf added the feature proposal New feature proposal label Feb 26, 2025
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Feb 26, 2025
@ghost1372
Copy link
Contributor

Don't wait for these changes. Many simple changes have been waiting to be implemented for years.
I suggest you use DevWinUI Templates
Most of the things you mentioned have been implemented.

@alvinashcraft
Copy link

I love these suggestions. I know @niels9001 has some strong feelings about the default templates too.

@dotMorten
Copy link
Contributor

I feel like you have many valid points here, but I don't think all of these should be added to the blank template. While I could see the existing template gets cleaned up a little, I don't want a bunch of opinioned stuff in a blank template. IMHO the blank template already has too much stuff in it with silly button-click stuff that you always have to remove.
That's not to say having an app set up with titlebar, styles, themes, views, page navigation frames etc doesn't have a place, but it's a different project template, and it is starting to get into Template Studio territory.

@niels9001
Copy link
Contributor

I feel like you have many valid points here, but I don't think all of these should be added to the blank template. While I could see the existing template gets cleaned up a little, I don't want a bunch of opinioned stuff in a blank template. IMHO the blank template already has too much stuff in it with silly button-click stuff that you always have to remove. That's not to say having an app set up with titlebar, styles, themes, views, page navigation frames etc doesn't have a place, but it's a different project template, and it is starting to get into Template Studio territory.

@dotMorten Any thoughts on what you'd consider opinioned for a Blank Template? Using the new TitleBar would add additional XAML, but from a UX perspective it would still launch an empty, modern looking window (IMO this experience should be the default experience when developing a new WinUI app - also since WPF with Fluent Theming provides that experience as well).

Sure, the XAML wouldn't be 'blank' - but the end result would be.

@Balkoth
Copy link

Balkoth commented Mar 4, 2025

The titlebar is the prime example of things which should not be in the default template. It's broken since ages ago.
Searching for issues just in this repo currently yields 83 open ones.

Imho remove the unused stuff and for anything else create a new template or integrate into Template Studio.

@mdtauk
Copy link
Contributor

mdtauk commented Mar 4, 2025

You could have an Empty/Blank project template, with nothing added.

And then have a Modern App project template, with the Titlebar all wired up, and the default assets required such as an ico file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature proposal New feature proposal needs-triage Issue needs to be triaged by the area owners
Projects
None yet
Development

No branches or pull requests

7 participants