Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Customizing a specific Visual #5005

Closed
PureWeen opened this issue Jan 17, 2019 · 19 comments
Closed

Customizing a specific Visual #5005

PureWeen opened this issue Jan 17, 2019 · 19 comments

Comments

@PureWeen
Copy link
Contributor

PureWeen commented Jan 17, 2019

Spec for adding properties to customize the behavior of a visual

  • Button Styles
    There are 4 button styles in material (https://material.io/design/components/buttons.html#specs): Contained (current style), Border, Text, Toggle / Icon. We could create an attached property that allows us to set this style: Material.ButtonStyle="Contained". One thing to note with this is that Android will be hard, if not impossible, to dynamically change. iOS just has a theme that you apply (not so sure if it supports undoing a style and may not actually work). Android has a style resource that probably needs to be applied in the constructor of the renderer. To support dynamic changes like this, we will probably not be able to use the "fast renderer" style and would need to use the ViewRenderer<T, T> base. iOS is already using this, so we can always recreate the control, but for Android we may lose the optimizations gained.
  • Entry / Editor Styles
  • Frame / Card Styles

Attached Properties

<Button material:Button.Style="Outline"></Button>

Pros

  • Attached properties can easily be split up according to the Element it's going to be applied to.

Cons

  • having to import custom namespaces is cumbersome for developers.

Specify the renderer with dotnet MAUI

Because dotnet MAUI inverts the dependencies and now a Button knows about its renderer we could use that detail to customize visual

dotnet/maui#28

<Button>
   <Button.Renderer>
     <MaterialButtonRenderer Style="Outline" >
         <MaterialButtonTemplate Style="Outline"  />
     </MaterialButtonRenderer>
   </Button.Renderer>
</Button>

Once we have xplat controls we could also use this same technique

<Button>
   <Button.Renderer>
     <ControlTemplateRenderer Style="Outline" >
         <ControlTemplate>
               <Grid></Grid>
         </ControlTemplate>
     </ControlTemplateRenderer>
   </Button.Renderer>
</Button>

Templating

If the user specifies a MaterialButtonTemplate than they don't have to specify the Material Visual. This doesn't obsolete Visual though because Visual is still used to hierarchically style an application. When you apply Visual at the parent level it will indicate what control template to use down the hierarchy

<Button>
     <VisualTemplate>
         <MaterialButtonTemplate Style="Outline"  />
     </VisualTemplate>
</Button>

outlined

<Button>
     <VisualTemplate>
         <MaterialButtonTemplate Style="Text"  />
     </VisualTemplate>
</Button>

text

This could possibly be extended to enabling users to set native properties as well

<Button>
     <VisualTemplate>
         <iOS:MaterialButton SomeSetOfIoSOnlyProperties >
         </OS:MaterialButton>
     </VisualTemplate>
</Button>

Pros

  • discoverable

CSS

Specifying visual attached properties in css will take the following format

visual-material-button-style

Backward Compatibility

  • Difficulty : N/A this is just a discussion of how to do it and then starting to add properties that map down to the native types
@arggrande
Copy link

Hi, here from the .NET Standup Video which mentioned this PR.

I love this feature ❤️

Would it be possible to specify something at the App level to auto-import the material namespace into the Views?

like App.UseMaterial = true;

Then you could have something like:

<Button MaterialStyle="Outline"></Button>

Also, regarding :

One thing to note with this is that Android will be hard, if not impossible, to dynamically change

What do you mean specifically by this? Do you mean the styles.xml file android uses?

@arggrande
Copy link

Ooo I like the suggestion in #5487 , around the assembly-level attribute attach.

@PureWeen
Copy link
Contributor Author

PureWeen commented Mar 8, 2019

@arggrande something like

<Button MaterialStyle="Outline"></Button>

Is a possible option. If we were to put all the material things into the same namespace then you wouldn't need the prefix. My only concern with this was discoverability or possibly having too many things show up by default

MaterialEditorProp1, MaterialEditorProp2, MaterialEditorProp3,
MaterialButtonProp1, MaterialButtonProp2, etc...

whereas with
material:Editor.Prop1

A conditional like you have is an interesting thought. I wonder if we could just enable intellisense if you set the visual

that'd be kind of neat

@ghost
Copy link

ghost commented Mar 8, 2019

@PureWeen we can use new XmlnsDefinitionAttribute to combine multiple CLR namespace with single XML namespace

@PureWeen
Copy link
Contributor Author

PureWeen commented Mar 8, 2019

@pranshaggarwal Right! Which is a good point. Because we could just leave it in its own namespace and then if people wanted to just combine them they could

@ghost
Copy link

ghost commented Mar 8, 2019

One Question, Doesn't this code make the xml invalid?
<Button MaterialStyle="Outline"></Button>

@PureWeen
Copy link
Contributor Author

PureWeen commented Mar 9, 2019

@pranshaggarwal yes :-/ that wasn't one of the case I had even initially proposed and just wasn't thinking of it straight when I commented above.

My main point with that still stands even with using XmlnsDefinitionAttribute
I wonder if that will put too many properties under one place

Material.ButtonStyle vs material:Button.Style

I played around with it a little bit here with using XmlnsDefinitionAttribute
https://github.com/xamarin/Xamarin.Forms/tree/visual_buttonstyle

The other nuance of XmlnsDefinitionAttribute is that the cross platform library has to have an init call or something calling into Xamarin.Forms.Material otherwise it runs into issues with the linker.

For example if you just call init on the platform project then the cross platform fails to compile with a namespace not found exception

@ghost
Copy link

ghost commented Mar 9, 2019

@PureWeen yes you are right, XmlnsDefinitionAttribute will not solve this problem.

Another option is to defines all the attached property in their respective class then have a clone of all the properties in one class(Material).

Btw if we are able to somehow simplify the attached property syntax as I describe here #5487 then we will not have to worry about this.

@davidortinau davidortinau pinned this issue Mar 9, 2019
@StephaneDelcroix
Copy link
Member

StephaneDelcroix commented Mar 12, 2019

to avoid reinventing the wheel again and again, I'd go for something very similar to PlatformSpecific

<Button m:Button.Style="Outline" />

everyone being able to redefine his own MaterialButton and include the properties directly. This is also what gives us the best options to move forward if we decide at some point to move the Material Style property directly to the Button class

@CliffAgius
Copy link
Contributor

I really like the simplicity of these especially @StephaneDelcroix cut down version to save on keyboard strokes after all you only have so many key presses in your life.

However I think that to have Button twice inside the statement is a waste so maybe something like:

<Button m:style="Outline" />

It's short sweet and to the point, maybe you could INCLUDE the longer version as well for readability:

<Button Material:style="Outline" />

just my thoughts, but great work and really like it.

@samhouts samhouts changed the title [Material,WIP] Add attached properties for Material specific attributes [Material] Add attached properties for Material specific attributes Jun 3, 2019
@jcmanke
Copy link
Contributor

jcmanke commented Aug 29, 2019

Leading and trailing icons are going to be a problem on text fields until xamarin/AndroidSupportComponents#201 is resolved.

@samhouts samhouts modified the milestones: 4.3.0, 4.4.0 Aug 29, 2019
@PureWeen
Copy link
Contributor Author

I added another option based on our conversations this past week

Templating

If the user specifies a MaterialButtonTemplate than they don't have to specify the Material Visual. This doesn't obsolete Visual though because Visual is still used to hierarchically style an application. When you apply Visual at the parent level it will indicate what control template to use down the hierarchy

<Button>
     <ControlTemplate>
         <MaterialButtonTemplate Style="Outline"  />
     </ControlTemplate>
</Button>

@samhouts samhouts removed this from the 4.4.0 milestone Nov 20, 2019
@samhouts samhouts added this to the 4.5.0 milestone Jan 6, 2020
@samhouts samhouts removed this from the 4.5.0 milestone Feb 11, 2020
@samhouts samhouts unpinned this issue Feb 15, 2020
@PureWeen PureWeen changed the title [Material] Add attached properties for Material specific attributes Customizing a specific Visual May 19, 2020
@kevinjpetersen
Copy link

@PureWeen I feel like if XF Visual Material could integrate with this WPF XAML Material Design Library, that would solve all of the issues. I'm currently using it for my WPF apps and it's amazing how much control I have!

https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit

@PureWeen
Copy link
Contributor Author

Yea! We'd looked at that a little with WPF and that would be really cool

Now if only someone would finish the UWP part of that one

@kevinjpetersen
Copy link

Yeah that's a downside I guess :/

@jfversluis
Copy link
Member

Thanks for this suggestion! As Xamarin.Forms is now in maintenance mode, this will not happen anymore for Xamarin.Forms. We're only adding bugfixes and stability fixes.

If this is still important to you, make sure to check the .NET MAUI repo and see if it's already on the roadmap. If not, feel free to open a discussion to discuss a change first or open an issue with a detailed feature request. Thanks!

@jfversluis jfversluis closed this as not planned Won't fix, can't repro, duplicate, stale Aug 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants