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

A more compact Style format #480

Open
VBAndCs opened this issue Mar 30, 2019 · 8 comments
Open

A more compact Style format #480

VBAndCs opened this issue Mar 30, 2019 · 8 comments
Labels
API suggestion Early API idea and discussion, it is NOT ready for implementation
Milestone

Comments

@VBAndCs
Copy link

VBAndCs commented Mar 30, 2019

Allow us to write Styles like this:

<Style Key="Style1" TargetType="Control">
   <Set
    Foreground = "#66603a"
    Background = "#fff4e4"
    BorderBrush = "Red"
    BorderThickness = ".5,.5,1.5,1.5"          
    FontFamily = "Times New Roman" 
    FontSize= "18" 
    FontWeight = "Bold" 
    FontStyle = "Oblique"
    Padding = "5" 
    Margin = "10" />

    <Handle MouseEnter ="Control_MouseEnter"/>
</Style>

this is more compact and more readable than:

<Style Key="Style1" TargetType="Control">
      <Setter Property="Control.Foreground" Value="#66603a" />
      <Setter Property="Control.Background" Value="#fff4e4"/>
      <Setter Property="Control.BorderBrush" Value="Red"/>
      <Setter Property="Control.BorderThickness" Value=".5,.5,1.5,1.5"/>          
      <Setter Property="Control.FontFamily" Value="Times New Roman" />
      <Setter Property="Control.FontSize" Value="18" />
      <Setter Property="Control.FontWeight" Value="Bold" />
      <Setter Property="Control.FontStyle" Value="Oblique"/>
      <Setter Property="Control.Padding" Value="5" />
      <Setter Property="Control.Margin" Value="10" />

    <EventSetter Event="MouseEnter"  Handler="Control_MouseEnter"/>
</Style>
@VBAndCs
Copy link
Author

VBAndCs commented Mar 30, 2019

For complex value, there is a little to enhance:

<Style>
        <Set BorderBrush="new()">
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Yellow" Offset="0.0" />
                    <GradientStop Color="Red" Offset="0.25" />
                    <GradientStop Color="Blue" Offset="0.75" />
                    <GradientStop Color="LimeGreen" Offset="1.0" />
                </LinearGradientBrush>
        </Set>
</Style>

instead of

<Style>
        <Setter Property="BorderBrush" >
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Yellow" Offset="0.0" />
                    <GradientStop Color="Red" Offset="0.25" />
                    <GradientStop Color="Blue" Offset="0.75" />
                    <GradientStop Color="LimeGreen" Offset="1.0" />
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
</Style>

@ryalanms ryalanms added the API suggestion Early API idea and discussion, it is NOT ready for implementation label Apr 2, 2019
@thomasclaudiushuber
Copy link
Contributor

Hi @VBAndCs,

great suggestion. You introduced a Set type with this snippet:

<Style Key="Style1" TargetType="Control">
   <Set
    Foreground = "#66603a"
    Background = "#fff4e4"
    BorderBrush = "Red"
    BorderThickness = ".5,.5,1.5,1.5"          
    FontFamily = "Times New Roman" 
    FontSize= "18" 
    FontWeight = "Bold" 
    FontStyle = "Oblique"
    Padding = "5" 
    Margin = "10" />

    <Handle MouseEnter ="Control_MouseEnter"/>
</Style>

But what if you want to create a style for another FrameworkElement, or a Control subclass? Then you need to find the properties of that other FrameworkElement or Control subclass on the Set type. That would mean there needs to be a Set type for every control type or the properties need to be dynamic somehow. This makes it complicated an I think this was a reason that led to the solution that we have today with Setters that can set any Dependency Property (That doesn't mean that there's not a better way to do it. :))

The second snippet in your first post doesn't need the Control class for the Property attributes, as you've specified it already in the TargetType. You can write it a bit shorter like this:

<Style Key="Style1" TargetType="Control">
      <Setter Property="Foreground" Value="#66603a" />
      <Setter Property="Background" Value="#fff4e4"/>
      <Setter Property="BorderBrush" Value="Red"/>
      <Setter Property="BorderThickness" Value=".5,.5,1.5,1.5"/>          
      <Setter Property="FontFamily" Value="Times New Roman" />
      <Setter Property="FontSize" Value="18" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="FontStyle" Value="Oblique"/>
      <Setter Property="Padding" Value="5" />
      <Setter Property="Margin" Value="10" />

    <EventSetter Event="MouseEnter"  Handler="Control_MouseEnter"/>
</Style>

Then the next one with the single setter for complex types. Instead of

<Style>
        <Setter Property="BorderBrush" >
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Yellow" Offset="0.0" />
                    <GradientStop Color="Red" Offset="0.25" />
                    <GradientStop Color="Blue" Offset="0.75" />
                    <GradientStop Color="LimeGreen" Offset="1.0" />
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
</Style>

you can write

<Style>
        <Setter Property="BorderBrush" >
            <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Yellow" Offset="0.0" />
                    <GradientStop Color="Red" Offset="0.25" />
                    <GradientStop Color="Blue" Offset="0.75" />
                    <GradientStop Color="LimeGreen" Offset="1.0" />
                </LinearGradientBrush>
        </Setter>
</Style>

when Issue #84 is fixed. The fix will be a one-liner, adding the ContentPropertyAttribute to the Setter class.

@VBAndCs
Copy link
Author

VBAndCs commented Apr 2, 2019

Hi @thomasclaudiushuber
There is no need to create a Set type. Parse <Set /> as an xml tag and get its Attr / Value pairs, then create a XAML Setter for each pair, and them to the Style. This can happen in run-time or in the precompiled BAML. This is a straight forward easy solution.
The only work to do, is make the editor / Xaml parser check that each attr written in the Set tag is a property in the TargetType with a valid value, of course with intellisense support.
This should be easier in the absence of the TargetType , where each attr (property) is fully qualified (i.e Control.Foreground = ...).
My aim here is to have a 2-stage Xaml parsing, to allow using some shortcut syntax, that expanded in run-time to the formal Xaml syntax.

@thomasclaudiushuber
Copy link
Contributor

Hi @VBAndCs,

ok, I understand. The idea is to extend the XAML Parser, so that it understands the Set tag as a shorthand syntax for the setters.

@VBAndCs
Copy link
Author

VBAndCs commented Apr 2, 2019

@thomasclaudiushuber
Exactly. I posted another proposal but in the XAML Slandered repo. In fact I don't know which repo is responsable for Xaml:
microsoft/xaml-standard#236

I had these ideas while I am working on Vazor. I use the VB XML literal to generate the Razor. I thought about using such technique with XAML somehow, or use xaml styles instead of CSS in Razor, but I found xamle style too verbose, so I thought of this. I add a middle stage between xml and razor, so, I though that this will be helpful in Xaml, especially it is dynamic and can be generated in run-time. I think we need to revise Xaml syntax and make it as shorter as possible.

@thomasclaudiushuber
Copy link
Contributor

HI @VBAndCs

I think posting this suggestion into this repo is good, as this is the official WPF repo.
For UWP XAML this repo is the way to go: https://github.com/Microsoft/microsoft-ui-xaml

Thanks,
Thomas

@stevenbrix stevenbrix added this to the Future milestone Apr 3, 2019
@stevenbrix
Copy link
Contributor

Thank you @VBAndCs and @thomasclaudiushuber for the awesome discussion here! I think both https://github.com/Microsoft/microsoft-ui-xaml and here are a good place to open issues like this, quite a few of us work on both technologies so it will be seen. I personally think any improvements like this should be synchronized across UWP, WPF, and Xamarin.Forms.

It's unfortunate what has happened to https://github.com/Microsoft/xaml-standard repo, although i'm hopeful that we can still align XAML dialects without necessarily creating a "XAML standard".

@chucker
Copy link

chucker commented Apr 21, 2020

It seems nobody has mentioned Xamarin.Forms CSS support.

Like WPF, Xamarin.Forms has support for XAML-based styles using resource dictionaries (see e.g. here), but it adds an alternate syntax in the form of (modified) CSS.

This is interesting because:

  • although this is a slightly different dialect (for example, there's a notion of "match this type as well as ones that inherit from it"), web developers will quickly be familiar
  • while XML is a good fit for the controls tree, I'm not sure it was ever a good idea to represent styles in it

I would love to see some collaboration so that an evolved form of Xamarin.Forms's CSS can be used in WPF as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API suggestion Early API idea and discussion, it is NOT ready for implementation
Projects
No open projects
Development

No branches or pull requests

5 participants