Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

XAML MVVM Binding Extensions to simplify Markup and integrate VIEW with VIEWMODEL and ViewModel Attributes #236

Closed
cesarchefinho opened this issue Apr 29, 2022 · 20 comments

Comments

@cesarchefinho
Copy link

Describe the problem

XAML is too verbose and cant read from anotations attibutes like validatos, data type etc in ViewModel

also XAML does not have and Validation Error mecanism for individual control error messages binded to ViewModel

Describe the solution

Binding Extensions MVVM Proposal to WINUI3 and UWP

An Extension to XAML language that simplify markup and expand XAML capabilities
by automatcaly bind control to ViewModel,
display validation error messages individualy per control,
and read all possible ViewModel Annotations to control without any coding

things like this

                    <!-- (PasswordBox , but any control, like Textbox, combobox, radio buttons, etc) -->

                    <PasswordBox 
                                Header="read DisplayName from anotations on view model"
                                Description=""read Error on viewmodel validation events"
                                PlaceholderText="read DisplayDescription from anotations on view model"
                                TextboxMask="read DisplayFormat from anotations on view model"
                                InputScope="Read best input scope based on anotations and viewmodel property"
                                Text="{x:Bind ViewModel.PasswordProp}"
                                MaxLength=""read all validation attributes from anotations on view model"
                                etc...etc...etc
                        />

simple will be this in markup:

                    <PasswordBox 
                                be:MVVM.ViewModel="{x:Bind ViewModel}"
                                be:MVVM.PropertyName="PasswordProp" />

the be:MVM extensions make all binding to you based on anottations of view model
also the be.MVVM extension use ObservableValidator and ObservablePropertyes
also the be:MVVM resolve binding to indexed string array attribute of collumns errors (bug in winui3 workedarrounded by be:MVVM)
also suport display error messages in TextBlock other than description property for controls that dont have Description

example:

                      <TextBlock Foreground="DarkRed" x:Name="AcceptErrorControl" />

Suported controls

        PasswordBox 
        AutoSuggestBox 
        NumberBox 
        RatingControl 
        RadioButtons 
        Slider 
        TimePicker 
        ComboBox 
        ListBox
        CheckBox 
        RadioButton 
        DatePicker 
        CalendarDatePicker
    TextBox           

**IT IS WORKING AND IS FUNCTIONAL

Also works on UNO in All Platforms AND in WINUI3 and UWP**

Alternatives

Waste a lot of time

Additional info

It is already implemented, i want to contribute to Microsoft

Help us help you

Yes, I'd like to be assigned to work on this item.

@ghost
Copy link

ghost commented Apr 29, 2022

Hello, 'cesarchefinho! Thanks for submitting a new feature request. I've automatically added a vote 👍 reaction to help get things started. Other community members can vote to help us prioritize this feature in the future!

@cesarchefinho
Copy link
Author

cesarchefinho commented Apr 29, 2022

also for previous example here is your viewmodel

public partial class ExtendedObservableValidator : ObservableValidator 
{
   // ... lot of goodies
   // but 
   
    [IndexerName("Item")]
    public string this[string columnName] =>
        string.Join(Environment.NewLine,
                    (from ValidationResult e 
                       in GetErrors(columnName) 
                   select e.ErrorMessage));

    public void OnErrorsChanged(object sender, DataErrorsChangedEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(e.PropertyName))
        {
            OnPropertyChanged("Item[]");
        }
        else
        {
            OnPropertyChanged($"Item[{e.PropertyName}]");
        }
    }
}

public partial class UserViewModel : ExtendedObservableValidator 
{
        [Display(Name = "Username", Description = "Your Username in format 999.999.999-99")]
        [DisplayFormat(DataFormatString = "999.999.999-99")]
        [NotEmpty(ErrorMessage = "Username Is Required", EmptyValue = "   .   .   -  ")]
        [StringLength(maximumLength: 14, MinimumLength = 11, ErrorMessage = "Username must be 14 or 11 digits !")]
        [ObservableProperty]
        private string username = String.Empty;

        [Display(Name = "Password", Description = "Type your password Here")]
        [Password]
        [Required(ErrorMessage = "Por favor, digite a senha.")]
        [StringLength(maximumLength: 16, MinimumLength = 6, ErrorMessage = "Password must be at minumum 6 chars e maximum of 16 chars !")]
        [ObservableProperty]
        private string passwordProp = String.Empty;
}

@cesarchefinho
Copy link
Author

if someone from Microsoft aprove this especification I will submit source code here

@michael-hawker
Copy link
Member

@cesarchefinho we're close to opening up our Toolkit Labs CommunityToolkit/WindowsCommunityToolkit#4487. That'll be a place to start a proposal for something like this and gather more feedback/input from the community on an implementation. Though we can gather some of that here now. @Arlodotexe @Sergio0694 @mrlacey would be interested in your thoughts.

In general though from my perspective, part of the massive effort we put towards creating the MVVM Toolkit into the Community Toolkit was around trying to keep things simple and being a reference implementation on top of the base C# interfaces. Something that was easy for folks to pick up and use in whichever pieces they need.

Having a more specific platform abstraction that imposes a specific way of doing things goes against those principles we adopted though. It could also be confusing to have two types of MVVM patterns intermingled across the Toolkits in this fashion.

This approach also seems to mix a lot more of the View and the ViewModel paradigms together breaking the notion of what MVVM is supposed to represent. And wouldn't this make it harder to localize the UI properties?

@cesarchefinho
Copy link
Author

This approach also seems to mix a lot more of the View and the ViewModel
paradigms together breaking the notion of what MVVM is supposed to represent.
And wouldn't this make it harder to localize the UI properties?

No, because dataannotation attributes already have support for localization and strings resources..

This aproach dont mix the things.

Actualy we have to descrieve propertyes in View
and again descrive the same properties in model. A lost of time, A duplication of information and a source of bugs

In other words we need to make tuo times the same thing !

with this aproach we only make the model
and view read things from annotation properties of model

and this is an extension, the user can adopt this metodology or not

but think with me,

if you have to put in xaml
Header="Name of user"
Tooltip=""Type here the name of user"

and in viewmodel

[Display(DisplayName="Name of user", Description = "Type here the name of user")]

you have the same information in tuo places and if you change something in xaml like
DisplayName="SocialSecurityID of user" inster of "name of user" but forget to change in viewmodel, we have problens

It is bether tu put all information only in annotations of view model

@mrlacey
Copy link
Contributor

mrlacey commented May 2, 2022

This seems an interesting idea but the vagueness of the outline and partial code samples leave lots of open questions.

For starters:

  • Are be:MVM, be.MVVM, & be:MVVM meant to be all the same or are they deliberately different?
  • This feels like it could be a framework all of its own. How does it work with other common coding conventions and frameworks? Can it?
  • Can you show a complete sample of something simple so it's possible to directly see comparable versions of "the same thing" side by side?
  • With a lot of the "cleverness" happening (presumably) at runtime, what impact does this have on performance and the ability to see (debug) what is actually output?
  • Is it all happening at runtime or is there any design or compile-time checking that can be done to help catch any issues as early as possible?
  • As you haven't shown how it works with localization, can you?
  • How extensible is it? What if someone wanted to add another (custom) attribute to a property (for example with custom validation logic) how could they have this link into what happens in the XAML?
  • [How] could this work with custom/user controls? Or is it limited to specific controls?
  • Your example of not needing to specify "Name of user" in the View (Header) and ViewModel (DisplayName) seems like something that shouldn't need to be done anyway. Can you expand more to show what you're trying to do away with?

@Sergio0694
Copy link
Member

As of right now, this proposal is not actionable. If new APIs are being proposed, there should be an actual API breakdown that can be reviewed. Right now I don't really understand what APIs are actually being proposed, how they would work, or how they would be used 🙂

@cesarchefinho
Copy link
Author

cesarchefinho commented May 3, 2022

As of right now, this proposal is not actionable. If new APIs are being proposed, there should be an actual API breakdown that can be reviewed. Right now I don't really understand what APIs are actually being proposed, how they would work, or how they would be used 🙂

the api is

«anycontrol be:MVVM.PropertyName="PhoneNumber" be:MVVM.ViewModel="vm" /»

and the infrastructure to make all things automatically binded from view model, independent of type of the control

And this dont break any existing API or modify XAML. It is an Upgrade like x:Bind upgraded x:Binding

@cesarchefinho
Copy link
Author

This seems an interesting idea but the vagueness of the outline and partial code samples leave lots of open questions.

For starters:

  • Are be:MVM, be.MVVM, & be:MVVM meant to be all the same or are they deliberately different?
  • This feels like it could be a framework all of its own. How does it work with other common coding conventions and frameworks? Can it?
  • Can you show a complete sample of something simple so it's possible to directly see comparable versions of "the same thing" side by side?
  • With a lot of the "cleverness" happening (presumably) at runtime, what impact does this have on performance and the ability to see (debug) what is actually output?
  • Is it all happening at runtime or is there any design or compile-time checking that can be done to help catch any issues as early as possible?
  • As you haven't shown how it works with localization, can you?
  • How extensible is it? What if someone wanted to add another (custom) attribute to a property (for example with custom validation logic) how could they have this link into what happens in the XAML?
  • [How] could this work with custom/user controls? Or is it limited to specific controls?
  • Your example of not needing to specify "Name of user" in the View (Header) and ViewModel (DisplayName) seems like something that shouldn't need to be done anyway. Can you expand more to show what you're trying to do away with?

Are be:MVM, be.MVVM, & be:MVVM meant to be all the same or are they deliberately different?

MVVM is only a pleasant sugar name, can be other name like be:AnnotationBinder

This feels like it could be a framework all of its own.

Yes can be, but I will prefer to donate it to Microsoft in advance of community and for broader audience

How does it work with other common coding conventions and frameworks? Can it?

Yes, It have no dependencies to other things than ComponentModel.DataAnotations Attributes and can easily integrated on any Model View Framework

Can you show a complete sample of something simple so it's possible to directly see comparable versions of "the same thing" side by side?

I will provide an sample.

The difference is that you don't put anything in XAML other than the property name of binded item in XAML and all other information of this property is readed from Attributes of this property from ViewModel.

Things like Header, PlaceHolder, Tooltip, Mask, Validation (error messages), InputScope (from DataType), I Say error messages ? they are binded from ObservableValidator class viewlmodel to Description of controls that have it and to other TextBlocks controls when not have it.

And a lot of other things, all with only a 2 lines of XAML code.

With a lot of the "cleverness" happening (presumably) at runtime, what impact does this have on performance and the ability to see (debug) what is actually output?

The impact is the same of using Binding versus x:Bind but it is the first version.

When the framework is stabilezed we can make an compiler version like source generators that Modify XAML before compilation and make things statically and not at runtime.

Is it all happening at runtime or is there any design or compile-time checking that can be done to help catch any issues as early as possible?

All checks are compiled in Attributes in ViewModel statically.
So errors in runtime is unexpected, but in future version the runtime can be substituted by compile time (something like source generators)

As you haven't shown how it works with localization, can you?

The same way you use localization in AttributesValidators, using resources and language
Be dont put any string in XAML the messages is readed from anottations and binded to XAML, and it dont interfere with localization that you already made in ViewModel.

How extensible is it?

Very Extensible, you cant configure the way of binder manipulate new validators and new attributes to Binder at startup application but it is a first version, a lot of things ca be possible in future.

What if someone wanted to add another (custom) attribute to a property (for example with custom validation logic) how could they have this link into what happens in the XAML?

be:MVVM works with any attributes, including custom user attributes

[How] could this work with custom/user controls?

The same way it works with normal controls, it use the bind infrastructure and ComponentModel.DataAnottions, works on any level of XAML, including Page, Normal Controls, Custom Controls, User Controls, etc

Or is it limited to specific controls?

It is Limeted only to bind the main property of knowed controls (Text for TextBox, SelectedValue for Listbox, etc), But this can be user configured and if not configured by user, be:MVVM will take care of all other properties and the user can bind main property in old way. Anyway we dont wate time coding lot of tedius code

Your example of not needing to specify "Name of user" in the View (Header) and ViewModel (DisplayName) seems like something that shouldn't need to be done anyway. Can you expand more to show what you're trying to do away with?

If you made view model and XAML indenpendly, you write 2 times. How can we dont neeed to be done ? Please explain me.

@Sergio0694
Copy link
Member

I feel like I should repeat this: as it currently stands, this issue is not actionable, as this is (presumably) meant to be an API proposal, but there is no API being proposed. As I mentioned, this needs to have an API breakdown so we can actually see the proposed API surface you'd like to contribute. As a reference, you can take a look at these issues: CommunityToolkit/WindowsCommunityToolkit#4300, CommunityToolkit/WindowsCommunityToolkit#3530.

I'm also quite worried about the fact this proposed feature, as far as I can tell, will heavily rely on reflection, and I don't think that's the direction we should be moving towards. It might be acceptable for cases where viewmodels use validation, since that's already not trimming friendly, but not in general cases where viewmodels just use MVVM without validation.

@michael-hawker
Copy link
Member

@cesarchefinho do you have your code in an existing repository somewhere that folks could look at or try directly?

@cesarchefinho
Copy link
Author

I feel like I should repeat this: as it currently stands, this issue is not actionable, as this is (presumably) meant to be an API proposal, but there is no API being proposed. As I mentioned, this needs to have an API breakdown so we can actually see the proposed API surface you'd like to contribute. As a reference, you can take a look at these issues: CommunityToolkit/WindowsCommunityToolkit#4300, CommunityToolkit/WindowsCommunityToolkit#3530.

I'm also quite worried about the fact this proposed feature, as far as I can tell, will heavily rely on reflection, and I don't think that's the direction we should be moving towards. It might be acceptable for cases where viewmodels use validation, since that's already not trimming friendly, but not in general cases where viewmodels just use MVVM without validation.

Dont Worried about reflection, this is the first version and all reflections that today is made in runtime can be eliminated and made at compile time to generate non reflection code that is statically compiled.

And this extension is an option to user, the user can use this extension to code fast when is appropriate or user can do thinks in the traditional way...

@cesarchefinho
Copy link
Author

@cesarchefinho do you have your code in an existing repository somewhere that folks could look at or try directly?

if you authorize i can post a code here

@Sergio0694
Copy link
Member

There is nothing to authorize, you're free to post code you wrote wherever you want, you own that.

@michael-hawker
Copy link
Member

@cesarchefinho do you have your code in an existing repository somewhere that folks could look at or try directly?

if you authorize i can post a code here

@cesarchefinho why don't you create your own repository on your own account first to show more about how your idea works with a sample/example project?

There's a lot of gaps here that we're not able to follow based on your brief textual descriptions.

@cesarchefinho
Copy link
Author

sourcecode.zip

this is the complete first version implementation of binding extensions and an sample forrm and view model

@cesarchefinho
Copy link
Author

@cesarchefinho do you have your code in an existing repository somewhere that folks could look at or try directly?

if you authorize i can post a code here

@cesarchefinho why don't you create your own repository on your own account first to show more about how your idea works with a sample/example project?

There's a lot of gaps here that we're not able to follow based on your brief textual descriptions.

i made an repository

https://github.com/cesarchefinho/MVVMBindingExtensions

@michael-hawker
Copy link
Member

i made an repository

https://github.com/cesarchefinho/MVVMBindingExtensions

Thanks @cesarchefinho for the repo, note that the Toolkit is licensed under an MIT license, I noticed you made your repo GPL 3.0. Do you mind changing it? Makes it easier for us to look at or consume later if something were to happen to you, or someone else wants to pick it up and contribute or help you contribute it to the Toolkit or another .NET or .NET Foundation project later (as the majority of them use MIT or Apache 2).

@cesarchefinho
Copy link
Author

i made an repository
https://github.com/cesarchefinho/MVVMBindingExtensions

Thanks @cesarchefinho for the repo, note that the Toolkit is licensed under an MIT license, I noticed you made your repo GPL 3.0. Do you mind changing it? Makes it easier for us to look at or consume later if something were to happen to you, or someone else wants to pick it up and contribute or help you contribute it to the Toolkit or another .NET or .NET Foundation project later (as the majority of them use MIT or Apache 2).

changed to MIT license. Thanks.

@cesarchefinho
Copy link
Author

i made an repository
https://github.com/cesarchefinho/MVVMBindingExtensions

Thanks @cesarchefinho for the repo, note that the Toolkit is licensed under an MIT license, I noticed you made your repo GPL 3.0. Do you mind changing it? Makes it easier for us to look at or consume later if something were to happen to you, or someone else wants to pick it up and contribute or help you contribute it to the Toolkit or another .NET or .NET Foundation project later (as the majority of them use MIT or Apache 2).

If you have any comments or suggestions for me about this extensions, please make it.

I also don't have the knowledge to implement an compiler time version of this without reflection.

If you have any information about xaml compilation phase or if you want to contribute with coding, please tell me.

Thanks

@Arlodotexe Arlodotexe transferred this issue from CommunityToolkit/WindowsCommunityToolkit Jul 28, 2022
@CommunityToolkit CommunityToolkit locked and limited conversation to collaborators Jul 28, 2022
@Arlodotexe Arlodotexe converted this issue into discussion #237 Jul 28, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

4 participants