Search code examples
c#asp.netmvvmbindingdotvvm

Dotvvm run-time binding to 'object' type


i have this class

public class Property{
     public string Name {get;set;}
     public object Value {get;set;} 
}

i want to create list of the above class List<Property> and dynamically add Mark Up Controls Code only , so as their website they have an example HERE and what i did to that example is adding a public property of type Property to the TextBoxWithLabel class and changed the setter of the above example for binding as follows:

    [MarkupOptions(AllowHardCodedValue = false)]
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set {
            SetValue(TextProperty, value);
            Property.Value = value;
        }
    }
    public static readonly DotvvmProperty TextProperty
        = DotvvmProperty.Register<string, TextBoxWithLabel>(c => c.Text, "");

when i run the app and type something in the input field, the Value property of Type Property still null and here is where i'm stuck i tried also to debug setter and it turns out it does not reach there so there is problem with run-time binding, which is 'as their example' this line of code

textBox.SetBinding(TextBox.TextProperty, GetValueBinding(TextProperty));

any help will appreciated :)

EDIT:

for more clarification,i have page called MainAppPage and Markup Control with code behind called ContentControl simply , MainAppPage passes List<Property> to ContentControl using this in MainAppPage <controls:ContentControl Instance="{value: ClassObject}"/> then ContentControl start iterating through List<Property> and creating InputField's that derive from HtmlGenericControl

InputField's rendering like a charm in ContentControl only thing is not working is binding , so again, how to bind Property.Value to InputField.Text so any changes happens in UI from user reflects on Property.Value after the InputField gets unfocused like any other MVVM pattern ?


Solution

  • DotVVM does not assign to the property usning the setter, is sets the underlying property store in DotvvmBindableObject instead. It's very simmilar what WPF does with their DependencyProperty, it's needed to represent the data bindings. You can actually completely omit the C# property declaration, declaring the field TextProperty and calling the DotvvmProperty.Register is enough to declare a property for dotvvm.

    Other "problem" is that the controls do not store any data, everything has to be persisted in the view model. You can only use the control properties to data-bind a view model property. I think we are running here into a XY problem, I can only tell why your code does not work, but I have no idea what are actually trying to do...

    Anyway, if you just want to "bind" your control to a view model property, have a look at https://www.dotvvm.com/docs/tutorials/control-development-markup-controls-with-code/2.0. You can declare the property like that:

    [MarkupOptions(AllowHardCodedValue = false)]
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DotvvmProperty TextProperty
        = DotvvmProperty.Register<string, TextBoxWithLabel>(c => c.Text, "");
    

    Use it in the markup of you control

    @baseType FullName.Of.YourControl
    {{value: _control.Text}}
    

    And use the control in your page (or other control)

    <cc:YourControl Text="{value: _this.Property.Value}" />