microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.31k stars 676 forks source link

Proposal: Support ThemeShadow entirely within XAML #2772

Open robloo opened 4 years ago

robloo commented 4 years ago

Proposal: Support ThemeShadow entirely within XAML

Summary

I know I'll get some flack for calling this a bug but I consider it one :) ThemeResource cannot be used without registering the control with the shadow in code-behind. This is a design bug in the way ThemeShadows are implemented. It breaks MVVM and lookless control principles as a shadow is entirely a styling choice.

Expected behavior

<Grid>
    <Grid.Resources>
        <ThemeShadow x:Name="SharedShadow" />
    </Grid.Resources>

    <Grid x:Name="BackgroundGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />

    <Rectangle x:Name="Rectangle1" Height="100" Width="100" Fill="Turquoise" Shadow="{StaticResource SharedShadow}" />

    <Rectangle x:Name="Rectangle2" Height="100" Width="100" Fill="Turquoise" Shadow="{StaticResource SharedShadow}" />
</Grid>

Should produce:

sharedshadow

Without having to add the following in code behind (I realize Translation can already be set in XAML).

SharedShadow.Receivers.Add(BackgroundGrid);

Rectangle1.Translation += new Vector3(0, 0, 16);
Rectangle2.Translation += new Vector3(120, 0, 32);

https://docs.microsoft.com/en-us/windows/uwp/design/layout/depth-shadow

Rationale

Slowly MVVM and lookless control principles are getting broken. We need to maintain the ability to style shadows entirely within XAML. This came up when talking about styling a new control that has a a selected color that should have a drop-shadow effect. The shadow receiver would need to become a template part and registered in code-behind with the current ThemeShadow implementation. It doesn't make sense that an additional template part should be required for this situation. We need the ability to do things like shadows directly and entirely in XAML:

image

Scope

Capability Priority
Remove the need to register shadow receivers before use or add ability to register in XAML Must
robloo commented 4 years ago

@ranjeshj @StephenLPeters What is Microsoft's position on this? I keep seeing the lookless control concepts getting violated with new feature additions. ThemeShadow is one case, the new ProgressRing Lottie animations are another (although there is a hacky work-around). A control's style and re-templating should not depend on code-behind at all.

@chingucoding Voices a different opinion and it's the same I've heard from @jevansaks before. Therefore, I wonder if Microsoft is really moving away from MVVM and lookless controls (i.e. re-templating).

marcelwgn commented 4 years ago

A control's style and re-templating should not depend on code-behind at all.

This is very hard to achieve, especially with growing complexity!

The issue is that it's hard to have a complex and fully functional control which is also easy to retemplate (TabView, NavigationView etc). I would also love to have every control be easily be retemplateable, but this would come at the cost of functionality in a lot of cases. Ideally developers shouldn't have the need to retemplate but rather use existing customization options such as control properties or lightweight styling. But that's just my opinion on this.

marcelwgn commented 4 years ago

Regarding your proposal:

Would putting it inside the resources of a page or control automatically make that the receiver? How would multiple receivers work with that?

Also: I think your sample needs the translation properties, if that should be an all XAML sample.

robloo commented 4 years ago

This is very hard to achieve, especially with growing complexity!

Well, I meant the link is template parts. Template parts are always required but should be kept to a minimum amount. As we discussed, I don't want to add template parts just to be a shadow receiver.

Would putting it inside the resources of a page or control automatically make that the receiver? How would multiple receivers work with that?

Ideally, by default, whatever control(s) are underneath are the receiver. A new property like IsShadowReceiver="False" could be added to override this behavior and make a control invisible for shadows (similar to hit testing). A shadow should be added in the compositing process and I don't understand why there is added complexity to make it work. There are likely implementation limitations I'm unaware of in how shadows work.

Also: I think your sample needs the translation properties, if that should be an all XAML sample.

Yes, I just copy-pasted for now. I'll update it as the discussion progresses.

michael-hawker commented 4 years ago

🦙 @robloo we have a proposal for this in the Toolkit here which should be in our 7.0 release. I already prototyped a POC that is working.

There's other things to consider here, especially to use these in any library components as I'd imagine that'd eat into the total limit of shadows which is small, see #2132.

robloo commented 4 years ago

@michael-hawker Great, that should be quite useful in the toolkit! Fundamentally, I don't understand this shadow limit either. I'll follow-up with that over on your other issue.

mdtauk commented 4 years ago

Xaml elements could get an Elevation property which applies the Vector 3 to the Z index value

robloo commented 4 years ago

Concerning the discussion about re-templating in general: I notice a while ago ALL the documentation seemed to disappear for re-templating specific controls. You used to be able to go to Microsoft docs online and see the default template as well as which parts were required. This documentation for each control is really critical for developers to understand specific quirks and concerns when re-templating is required for any given control. It would go a long way to helping alleviate @chingucoding concerns that re-templating is dangerous -- it would be far less dangerous if it was documented for every control.

@mdtauk, could you elaborate? I'm not sure how that is different from Translation.

marcelwgn commented 4 years ago

Concerning the discussion about re-templating in general: I notice a while ago ALL the documentation seemed to disappear for re-templating specific controls. You used to be able to go to Microsoft docs online and see the default template as well as which parts were required. This documentation for each control is really critical for developers to understand specific quirks and concerns when re-templating is required for any given control. It would go a long way to helping alleviate @chingucoding concerns that re-templating is dangerous -- it would be far less dangerous if it was documented for every control.

I think the main problem with that kind of documentation is that it is a lot of work to keep it up to date and requires a lot of effort. You would need to update that every time you change the template, which can happen quite often.

mdtauk commented 4 years ago

Concerning the discussion about re-templating in general: I notice a while ago ALL the documentation seemed to disappear for re-templating specific controls. You used to be able to go to Microsoft docs online and see the default template as well as which parts were required. This documentation for each control is really critical for developers to understand specific quirks and concerns when re-templating is required for any given control. It would go a long way to helping alleviate @chingucoding concerns that re-templating is dangerous -- it would be far less dangerous if it was documented for every control.

I think the main problem with that kind of documentation is that it is a lot of work to keep it up to date and requires a lot of effort. You would need to update that every time you change the template, which can happen quite often.

Link to Github Xaml ResourceDIctionaries?

robloo commented 4 years ago

I think the main problem with that kind of documentation is that it is a lot of work to keep it up to date and requires a lot of effort. You would need to update that every time you change the template, which can happen quite often.

@chingucoding I agree it's difficult but only more so now with WinUI separate from the windows templates/styles. With WinUI 3 everything is coming together again and it will make a lot more sense. Additionally, the parts of the documents you are concerned about could be auto-generated. All controls, at least in c#, should declare their parts:

[TemplatePart(Name = nameof(CurrencyBox.LayoutRoot), Type = typeof(FrameworkElement))]

Then the XAML could automatically be added to docs and the parts automatically detected.

The areas of the documentation I'm more concerned are notes from the original control authors. Those authors should provide quirks/instructions for downstream developers that may have to re-template. These notes shouldn't really change and don't need to be kept up-to date with automated tooling. I'm guessing Microsoft has lost this information internally too which is why bugs get re-introduced when the original control author is no longer working on it. Docs are key. Re-templating is fundamental.

marcelwgn commented 4 years ago

Link to Github Xaml ResourceDIctionaries?

What @robloo was referring to is also what parts of the template are necessary. For that, it is not enough to link to the XAML but you also need someone to sit down, decide what is necssary and document it.

Then the XAML could automatically be added to docs and the parts automatically detected.

Yes that is something one could do, though I already have found different places where I can see the default template (e.g. through Visual Studio which can generate you a copy of a control template).

The areas of the documentation I'm more concerned are notes from the original control authors. Those authors should provide quirks/instructions for downstream developers that may have to re-template. These notes shouldn't really change and don't need to be kept up-to date with automated tooling. I'm guessing Microsoft has lost this information internally too which is why bugs get re-introduced when the original control author is no longer working on it. Docs are key. Re-templating is fundamental.

Yes that is the main problem, as the control changes those would need to get updated again and again. And requiring the author of the control to do that would make it very difficult to contribute to controls.

mdtauk commented 4 years ago

Link to Github Xaml ResourceDIctionaries?

What @robloo was referring to is also what parts of the template are necessary. For that, it is not enough to link to the XAML but you also need someone to sit down, decide what is necssary and document it.

Then the XAML could automatically be added to docs and the parts automatically detected.

Yes that is something one could do, though I already have found different places where I can see the default template (e.g. through Visual Studio which can generate you a copy of a control template).

The areas of the documentation I'm more concerned are notes from the original control authors. Those authors should provide quirks/instructions for downstream developers that may have to re-template. These notes shouldn't really change and don't need to be kept up-to date with automated tooling. I'm guessing Microsoft has lost this information internally too which is why bugs get re-introduced when the original control author is no longer working on it. Docs are key. Re-templating is fundamental.

Yes that is the main problem, as the control changes those would need to get updated again and again. And requiring the author of the control to do that would make it very difficult to contribute to controls.

If I am understanding the problem properly - This is about those controls which use Template Parts right?

Could docs be generated from the code, that calls these out - so highlighting the controls' construction, and labelling those required parts.

This could be listed in the docs for the control itself, as well as in autocomplete and comments in the templates?

robloo commented 4 years ago

@chingucoding

Yes that is the main problem, as the control changes those would need to get updated again and again. And requiring the author of the control to do that would make it very difficult to contribute to controls.

Most styling changes when touching templates don't affect the logic and template parts. So there is a lesser chance this gets out of date. All development requires discipline keeping the documentation up to date (maybe that's just because I come from automotive where documentation standards are very stict?). Anyway, now you don't want to support re-templating and also don't want to document things!? ;) It's not too much work, it just needs to be clearly defined and enforced by the project maintainers. In most cases only when a brand new control is written or a template part added would this really have to be revisited.

Aside from general quirks/instructions. The most useful documentation is also 'why' template parts were added. It should be explained someplace what is going on internally that require these. In some cases, the backgrounds/Fill are automatically calculated. That should all be explained. It should also be explained which template parts are designed to be safely excluded.

Honestly, I don't understand how these fundamental lookless control concept pioneering with WPF are getting lost and yet we are still using XAML. We need to correct this before it gets impossible to correct. I know other UI frameworks don't take this approach and that's fine, it's a totally different concept though.

marcelwgn commented 4 years ago

If I am understanding the problem properly - This is about those controls which use Template Parts right? Could docs be generated from the code, that calls these out - so highlighting the controls' construction, and labelling those required parts. This could be listed in the docs for the control itself, as well as in autocomplete and comments in the templates?

Yes provided all of the template parts have been documented in code, theoretically you could auto generate the documentation for that.

Anyway, now you don't want to support re-templating and also don't want to document things!? ;)

I never implied either things ;) I just want to point out that both are a lot of work for limited reward, even if you say that we all need to have lookless controls. In my opinion, ideally, you wouldn't have to retemplate controls because they are already customizable enough through properties and lightweight styling and only in very specific scenarios a retemplate is needed to get the desired result.

Aside from general quirks/instructions. The most useful documentation is also 'why' template parts were added. It should be explained someplace what is going on internally that require these. In some cases, the backgrounds/Fill are automatically calculated. That should all be explained. It should also be explained which template parts are designed to be safely excluded.

Yes knowing why something was added is quite useful to know. I'm not sure what you mean by "backgrounds/Fill" here though.

mdtauk commented 4 years ago

I never implied either things ;) I just want to point out that both are a lot of work for limited reward, even if you say that we all need to have lookless controls. In my opinion, ideally, you wouldn't have to retemplate controls because they are already customizable enough through properties and lightweight styling and only in very specific scenarios a retemplate is needed to get the desired result.

Moving away from Lookless Controls would be a big change (should probably go hand in hand with a wholesale change from Xaml to Xaml Next) - and could be a good thing. But it would not be Xaml in the way it has existed since Avalon and WinXP's days.

Android and Apple have their own UI paradigms - none as flexible as Xaml for changing control designs - but with Rendering offloaded to GPUs, could there be a call for a new approach - without Xaml trees to parse, but deeper aspects of primitive shapes, shadows, etc?

robloo commented 4 years ago

@chingucoding

Yes knowing why something was added is quite useful to know. I'm not sure what you mean by "backgrounds/Fill" here though.

The control I wrote over the past few days renders custom backgrounds for sliders to show color gradients. That's just an example I had in mind. Other controls do things like this too though. It's very useful to understand what's going on behind the scenes (and the intention) without reading the code. Edit: before open-sourcing and the WPF reference, code wasn't even available for the most part.

@mdtauk I wholeheartedly agree with you. Like you said that's a paradigm shift. For now we should be consistent with what we have. XAML is getting old though and there are ideas for improving it or even going to a brand new Flutter-like or Blazor-like system.

marcelwgn commented 4 years ago

The control I wrote over the past few days renders custom backgrounds for sliders to show color gradients. That's just an example I had in mind. Other controls do things like this too though. It's very useful to understand what's going on behind the scenes (and the intention) without reading the code.

Oh right, I see. Yes, not needing to read the code to understand what happens under the hood is quite useful. However some controls are very complex and "under the hood" becomes quite a lot (see NavigationView or ItemsRepeater).

michael-hawker commented 4 years ago

Concerning the discussion about re-templating in general: I notice a while ago ALL the documentation seemed to disappear for re-templating specific controls. You used to be able to go to Microsoft docs online and see the default template as well as which parts were required. This documentation for each control is really critical for developers to understand specific quirks and concerns when re-templating is required for any given control.

🦙 Hey All (@robloo , @mdtauk, @chingucoding), think we got a bit off topic here. If you want to share all your thoughts on having templates better documented, I had an issue I filed on that subject over here: https://github.com/MicrosoftDocs/windows-uwp/issues/1870 (probably needs a better title). Though to my knowledge the UWP ones were never documented, it was only WPF that did this (they're still online).

robloo commented 4 years ago

@michael-hawker Yes, we were definitely getting off track for this issue. Thanks for linking to the relevant one, I didn't know it already existed and I'll copy some comments over to it.

I also could have sworn when UWP first released (years ago now) the docs looked very much like WPF for templates. What I remember looks exactly like the WPF docs though so it's possible I was just confusing the two.

robloo commented 1 year ago

Would be nice to make shadows more MVVM friendly and usable in XAML.