dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.08k stars 1.17k forks source link

.NET Core Theme Styles for WPF Controls #1402

Open vatsan-madhavan opened 5 years ago

vatsan-madhavan commented 5 years ago

Create a standard set of Theme Styles.

At present, an older copy of these styles can be found in Visual Studio, which were created in ~.NET 4.5 timeframeframe.

C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\aero.normalcolor.xaml
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\aero2.normalcolor.xaml
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\aerolite.normalcolor.xaml
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\classic.xaml
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\luna.homestead.xaml
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\luna.metallic.xaml
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\luna.normalcolor.xaml
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\DesignTools\SystemThemes\Wpf\royale.normalcolor.xaml

The theme specific XAML files (#865) do not contain enough information to be used as-is (#1146).

Further, we should work with the VS templating team to ensure that these update Theme Styles are available as an item-template and consumable by the VS IDE at design-time.

vatsan-madhavan commented 5 years ago

/cc @chabiss, @rladuca, @grubioe /cc @weltkante

weltkante commented 5 years ago

Are luna/royale themes useful for anything besides backwards compatibility for people referencing them, considering they are based on now unsupported Windows XP? I mean, they are referencing system parameters for colors and sizes which will never occur on a supported system. People can still reference them or copy XP-like styles from existing controls but they'll have to manually adjust them and replace system parameter references by actual values representative for XP systems. Even then some things like non-client areas will never look right because they were never rendered by WPF.

As this is now planning for 5.0, when moving on with WPF for .NET Core you'll probably have a hard time updating existing controls or styling new controls, considering you don't have any place to actually test those (unless you still keep WinXP test machines around just for testing the styles)

Berrysoft commented 5 years ago

I'm mostly agree with @weltkante 's opinion. However, I don't think we should simply remove the luna/royale themes, because it is a good template and tutorial for writing WPF styles. On the contrary, I think we should archive them. In addition, I suggest publishing all themes as separate nupkgs, because they are large and costs much more space when publishing self-contained WPF programs. We can choose which theme to include manually if they are distributed separately.

wjk commented 5 years ago

Since we discussing styles, when I adopt/start planning to contribute to 5.0 I would really, really appreciate some better-designed default styles for WPF apps. I keep joking that all the default WPF styles look like they were designed by the summer intern on his first day at Microsoft some fifteen years ago, and never touched by anyone since. @gix's PresentationTheme.Aero would be a great starting point, but it isn't quite compatible with .NET Core WPF as-is. (I tried changing the packaging to work correctly with Core WPF in https://github.com/gix/PresentationTheme.Aero/pull/2, but I could not excise the use of private reflection which was breaking the theme engine on Core.) Furthermore, as discussed in #110, a separate theme such as this one won't ever be a fully sufficient replacement for the visually sub-par originals.

I would also like to note that I would want to update/refine the Windows 7-era Aero theme, since I greatly prefer the look-and-feel of that theme over the (third-party and in-box) Windows 10-era themes. (Not to mention that some users are still using Windows 7, and I would want to fit into that version of Windows if at all possible.) I would have started work on this task some time ago, except that the theme assemblies are (still!) not open-source, and I cannot start from the XAML files in @vatsan-madhavan's original post because some parts of the Windows 7 theme are implemented in C#, and I want/need to convert it to 100% XAML. Although I agree with @Berrysoft's opinion on the Windows XP themes, please do not archive or delete the Windows 7 theme. Thanks!

mdtauk commented 5 years ago

With the upcoming WinUI 3.0 release, bringing updated control designs to XAML - perhaps it is time to bring out updated WPF control templates and updated WinForms/Windows GDI controls to match the styling (if not control size and spacing)

wjk commented 5 years ago

I had a thought about this issue. I could start work porting the PresentationTheme.Aero theme XAML into my fork of the WPF repo. I would create new theme assemblies to hold these styles (PresentationFramework.Aero.Win8, PresentationFramework.Aero.Win10, etc).

However, I quickly run into a problem: If I were to change UxThemeWrapper to use a more nuanced algorithm for choosing a theme, I would then break applications that depend on the use of the "Aero2" theme name, as discussed in https://github.com/dotnet/wpf/issues/1913#issuecomment-533259982. I tried writing code that falls back on Aero2 if the newer names are being used but a resource wasn't found, but I could not wrap my head around the resource lookup code.

I also could try dumping the newer styles into the existing Aero2 DLL, and modify UxThemeWrapper to return a different theme color (currently, it always returns NormalColor), but then I would run into the same compatibility issue. This time, my changes would break apps that expect Aero2.NormalColor.xaml to be used.

If anyone could give me some pointers on how to disentangle SystemResources (and wherever in PresentationFramework the lookup code for controls in third-party assemblies is found), I would greatly appreciate it. Thanks!

weltkante commented 5 years ago

Historically the theme engine is supposed to select the XAML files which match the native OS look and feel. Considering that the OS now has two "native" look and feels, win32 and UWP, the whole approach to theming needs to be thought over. I don't think the current engine will be flexible enough to support that, there's #1913 for opening up the theming engine but as I have brought up over there the theming engine is a feature for control authors not for application wide themes (so it would be more appropriate for your usecase than what OP of #1913 desires to use it for)

I don't think replacing the existing themes is the way to go, people will still want to match win32 Desktop themes. There probably could be an application switch to select between win32 and UWP themes.

If anyone could give me some pointers on how to disentangle SystemResources

You need to be more specific, do you mean how the resource dictionaries are resolved (which happens to have some code in that file) or how system resources are resolved? The latter is a big switch block in SystemResourceKey

and wherever in PresentationFramework the lookup code for controls in third-party assemblies is found

Third-party assemblies aren't special, if anything is special then its PresentationFramework itself, but other Microsoft assemblies are just like any other third party assembly, no distinction. All can use ThemeInfoAttribute to configure the lookup and its just that for PresentationFramework it defaults to "external assembly" while the VS generated attribute has other defaults.

weltkante commented 5 years ago

Also I think we are running offtopic on this particular issue, it wasn't about modernizing the themes, it was about getting up-to-date XAML published as part of the build process. Currently the XAML is included in VS so it is not in sync with any updates done in this repository (and considering you can reference different versions of the WPF nuget packages VS will have a hard time being in sync with anything once things start to change).

Modernizing the themes should probably have a separate issue and not be mixed with technical issues resolving around publishing XAML source for the designers.

bugproof commented 4 years ago

It would be cool to somehow override themes with BasedOn without special workarounds. Currently if you load a theme you can't customize controls anymore. It requires hackish workarounds.

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/PresentationFramework.Classic;component/themes/Classic.xaml"/>
    <ResourceDictionary Source="CustomClassicTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

https://stackoverflow.com/questions/2377055/override-overridden-wpf-theme https://stackoverflow.com/questions/4239714/why-cant-i-style-a-control-with-the-aero-theme-applied-in-wpf-4-0 https://stackoverflow.com/questions/4662052/how-do-i-override-style-in-a-specific-theme

Also, not all controls have x:Key so you could override button like:

<Style TargetType="{x:Type Button}" BasedOn="{StaticResource &#207;}">
    <Setter Property="Background" Value="Red"/>
</Style>

but it won't work for DataGrid for example.

<Style x:Key="{x:Type DataGrid}" TargetType="{x:Type DataGrid}">