Replies: 14 comments 34 replies
-
I think this discussion should also be forwarded to the owner of theming libs, like:
I am sure there is more ^^ |
Beta Was this translation helpful? Give feedback.
-
@grokys do you have any sample of how the new theme / style will look like without using /template/ ? In the PR I don't find it and also I can't imagine it to be honest. |
Beta Was this translation helpful? Give feedback.
-
I don't think we should completely remove nested But I do agree that we should recommend to NOT use it in control and theme libraries. As using ControlTheme without nested templates/template selectors is better performance wise and less error prone. |
Beta Was this translation helpful? Give feedback.
-
Btw, there's been a decent bit of discussion around this feature, but no-one's answered my question ;) What are your use-cases? |
Beta Was this translation helpful? Give feedback.
-
Apologies for another discussion. I am glad to see this is the public forum though as it's one of those things so fundamental to devs. I'm going to approach this at a high level to start: This at first seems like a solution to a problem that doesn't exist (from an app dev standpoint). I haven't heard anyone complain about the ability to drill into templates with selectors. In fact, it is one of the most powerful features with Avalonia's styling system. Personally, I thought it was amazing when I saw this functionality for the first time. It saves a lot of time. I also realize the concerns about public API surface area and the necessity to smoothly transition to Fluent v2 in the future for example. This kind-of puts frameworks in a no-win scenario where if you make everything "private" some devs still need it. And if you make things "public" devs complain when stiff breaks between major versions. However, as with everything, I don't think either of those two extremes is correct. Accessing templates should be allowed but only rarely or within a theme itself. Breaking is OK but silent breaking is the real issue. The Xaml compiler needs to detect and throw errors in this case. I think the compromise above of requiring named controls is a good middle road here. Additionally, removing this feels analogous to Microsoft trying to remove visual tree accessing methods and abstract away the default styling implementation from apps. Their reasoning was similar: microsoft/microsoft-ui-xaml#1331. I ended up collecting many use cases over time to show why this was a bad idea in principle. More fundamentally though, developers should be empowered to make the final decision themselves and for their own apps on doing things like accessing templates directly and making them inter-dependent. There are situations where the cost/benefit makes accessing the template directly an obvious choice. I can see countless examples over the years where the first recommendation is to do so. It really is a huge time saver (I don't have time to collect all the examples right now, nor do I think that is strictly necessary for a high-level, conceptual discussion). Functionality like this being removed is more for the sake of the framework maintainers. From that viewpoint it makes sense. But a framework isn't really written for the framework maintainers -- it's written for app developers. At the end of the day app developer needs must take priority for the framework to be most successful. With inter-dependencies in styles/themes, app code needs to change when default styles and themes are updated over the years. That's a normal thing in development though and would also be alleviated by splitting the themes up in separate nugets and allowing apps to use whichever theme wish (even old ones). Which leads to:
In my mind the base FluentTheme in core Avalonia should be extensible so DataGrid and ColorPicker can add to it. So they are still part of the "FluentTheme"; however, the dependency is one-way ColorPicker/DataGrid -> Core Avalonia (no two-way dependency). This is the same for FluentAvalonia and higher level themes. They should be able to extend the core fluent theme and take dependencies one-way. So everything is still cleanly layered: Core Avalonia -> ColorPicker/DataGrid -> FluentAvalonia. Bottom line though: |
Beta Was this translation helpful? Give feedback.
-
A template part is traditionally only those named controls used with code behind. Within templates themselves, of course elements can be named and used in styling but that is independent of code-behind and is not a template part with a "PART_" prefix. So we would confuse things a little if we called both template parts. |
Beta Was this translation helpful? Give feedback.
-
Hi, I just love using template selectors in Avalonia. It would be so sad to see them disapear. Developping a new way to style template with ControlTheme could be usefull i suppose (even if i don't need it now because with template selectors i can acheive everything i want), but it would be great if it could be an optional feature that doesn't replace template selectors. Avalonia doesn't have breaking changes since 0.10.0, it would be sad to have to replace all template selectors in existing code to solve a problem that i don't really understand and care. Please don't break everything, please don't force developers to rewrite working code, please add new features next to existing ones (and not instead of existing ones) and don't break things... Eviral |
Beta Was this translation helpful? Give feedback.
-
To add my 2 cents on the I'll often copy and paste large chunks of a control's style from the fluent theme and then go to town on tweaking values. My tweaks typically involve removing references to or overriding resources defined in the Accents directory with resources defined within my controls styles (keeping everything in one place). You can see an example of this with this Button style. I know I could have achieved 99% of what I desired by simply overriding existing resource values defined, but I found reasoning about the resource value particularly arduous. I'd find myself switching between multiple files and searching for the resource keys. For example, trying to style a In my mind, copying pieces of the existing control existing styles and overriding resource values within the same file made it easier and faster to make changes. While it adds unnecessary code and much duplication, it significantly reduced the need to bounce through multiple files as I traced values. By copying styles, including those using the I suppose the only reason I'm using the |
Beta Was this translation helpful? Give feedback.
-
I'm pulling this out part out as the "scope" of this change I think is relevant. @grokys has commented:
and
The intention long term (unless that has changed in the last 48 hours) is to remove \template\ selector support from styles someday as well. A lot of the comments are already taking that into consideration. That said, removing \template\ from ControlTheme is easier because its new. However, ControlTheme makes more sense to allow \template\ than Styles based on your logic. Simply put, ControlTheme IS the theme itself. It absolutely makes sense to reach in and change elements in it's own template or even nested templates. That makes total sense because a ControlTheme is defining the template.... why wouldn't it have access to it's own "internal" members? Style is outside the control theme and heavily used by app authors. Allowing it here is exposing it as a public API and is actually the worst case for it (by your reasoning, NOT mine). If you allow it in Styles you should allow it in the ControlTheme. If you are disabling it in one of the two it should be allowed in ControlTheme but disabled in Style -- by your own logic of encapsulation and locking down "public" APIs. |
Beta Was this translation helpful? Give feedback.
-
Another broad comment here: You are trying to steer this discussion just to examples. That can sometimes help move things forward in a rational way. However, it would be nice to see a much more democratic process for these types of fundamental decisions BEFORE they are made. There is a lot of knowledge in the users of Avalonia and they all have their own 'gut feeling' too that I think is relevant. I would normally like to see something like this discussion approached as "Should we keep /template/ support in selectors" rather than give me "\template\ selector use-cases" so I can make the final decision. You have a lot of bias already and I'm not sure any examples we give you will ever change your mind. Your reasoning is different and more fundamental. |
Beta Was this translation helpful? Give feedback.
-
I'm copying this over as well. #8479 (comment)
|
Beta Was this translation helpful? Give feedback.
-
I've tweaked the title and some wording a bit to make it clear that we're talking about nested template selectors in
Where the selector is reaching into the template of a separate control. Single levels of
Are absolutely fine, and expected. |
Beta Was this translation helpful? Give feedback.
-
I've just ran into this while trying to make a control that in simple form has a <ControlTheme ...>
<Style Selector="^:focus /template/ TextBox#Text /template/ Border#PART_BorderElement">
<Setter Property="BorderThickness" Value="0" />
</Style>
</ControlTheme> Obviously this doesn't work, I tried all sorts but in the end the only way I found that works is overriding the resources (couldn't seem to get the resources to apply via a style so had to set it directly): <ControlTheme ...>
...
<TextBox ...>
<TextBox.Resources>
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0</Thickness>
</TextBox.Resources>
</TextBox>
...
</ControlTheme> I think this is similar to other cases listed here but it would be nice if in my case the |
Beta Was this translation helpful? Give feedback.
-
I ran across another important use-case of this. I have a custom control that has a <!-- Switch to a Calendar Glyph -->
<Style Selector="^ /template/ DropDownButton#LayoutRoot /template/ fac|FontIcon#DropDownGlyph">
<Setter Property="Glyph" Value="" />
<Setter Property="FontFamily" Value="{DynamicResource ControlSymbolFontFamily}" />
</Style> (note this uses FluentAvalonia's DropDownButton ControlTheme). |
Beta Was this translation helpful? Give feedback.
-
As discussed in this PR and in particular this comment we're planning on disallowing nested
/template/
selectors with in the newControlTheme
feature (that is,/template/
selectors that probe into the template of an unrelated control).Existing
/template/
selectors in styles outside of control themes will continue working the same for the moment. We'd like to remove the/template/
selector in the long-term (with the exception of a single/template/
inside control themes) however because it breaks encapsulation and makes theme implementation details a public API.So I'd like to discuss the current use-cases for nested
/template/
selectors. In my initial port of the fluent theme toControlTheme
s I came across the following use-cases. If you have any more, please note them here.Modifying the colors of existing controls
Many controls need to modify the
:pointerover
,:pressed:
,:disabled
etc states in existing controls: for example the calendar needs to change the colors of these states to a specific resource: https://github.com/AvaloniaUI/Avalonia/pull/8479/files#diff-02d2f8266cc53d3b5141fdcc37693a1a177becf6fbb2ad5d890692296389dea6R47Adding additional states to existing controls
Sometimes a control hosted in a template needs to have additional states to those defined on the control itself. For example the individual
Button
s hosted in aSplitButton
have two additional states:checked
andflyout-open
: https://github.com/AvaloniaUI/Avalonia/pull/8479/files#diff-02d2f8266cc53d3b5141fdcc37693a1a177becf6fbb2ad5d890692296389dea6R47Modifying existing themes
This is a use-case outside
ControlTheme
where customers want to tweak an existing theme, such as the fluent theme in some way. I'd be interested to hear what tweaks people are applying in this way. My feeling is that modifying themes in this way is brittle, and we should be providing hooks to allow common customizations (which we already do to a degree by using resources for most things) or encouraging people to instead fork the theme.Beta Was this translation helpful? Give feedback.
All reactions