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

[Bug] BindingContext default behavior, on nested controls #10296

Open
Phenek opened this issue Sep 23, 2022 · 5 comments
Open

[Bug] BindingContext default behavior, on nested controls #10296

Phenek opened this issue Sep 23, 2022 · 5 comments
Labels
area-xaml XAML, CSS, Triggers, Behaviors platform/android 🤖 platform/iOS 🍎 platform/macOS 🍏 macOS / Mac Catalyst platform/windows 🪟 s/triaged Issue has been reviewed t/bug Something isn't working
Milestone

Comments

@Phenek
Copy link

Phenek commented Sep 23, 2022

Description

Hello,

I am trying to bind a Text Property of a control that is inside another, and it does not work.

Let me explain, I was creating kind of an Input layout, like so

public partial class InputLayout : Grid
{
    public static readonly BindableProperty LabelProperty =
        BindableProperty.Create(nameof(Label), typeof(Label), typeof(InputLayout), null, propertyChanged: LabelChanged);

    public static readonly BindableProperty InputViewProperty =
       BindableProperty.Create(nameof(InputView), typeof(InputView), typeof(InputLayout), null, propertyChanged: InputViewChanged);
       
     ...
       
    public Label Label
    {
        get => (Label)GetValue(LabelProperty);
        set => SetValue(LabelProperty, value);
    }

    public InputView InputView
    {
        get => (InputView)GetValue(InputViewProperty);
        set => SetValue(InputViewProperty, value);
    }
    
    ...
    
    private static void InputViewChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (bindable is not InputLayout intputLayout
            || newValue is not InputView inputView
            || inputView is not IFontElement fontElement) return;

        Grid.SetColumn(inputView, 2);
        Grid.SetColumnSpan(inputView, 1);
        Grid.SetRow(inputView, 1);
        Grid.SetRowSpan(inputView, 1);
        intputLayout.Children.Add(inputView);
    }
}

We should be able to use it like this, But the binding on the Entry does not work anymore...

<controls:InputLayout x:Name="_email" StyleClass="NormalInputLayout">

   <controls:InputLayout.Label>
      <Label Text="Email"/>
   </controls:InputLayout.Label>

   <controls:InputLayout.InputView>
      <Entry
           Keyboard="Email"
           IsTextPredictionEnabled="false"
           Text="{Binding Email, Mode=TwoWay}"/>
   </controls:InputLayout.InputView>
   
</controls:InputLayout>

I also tried to create a intermediate Bindable Text Property in my InputLayout, then bind it progamaticaly, but it also doesn not work.

InputView.SetBinding(InputView.TextProperty, new Binding(nameof(Text)) { Source = this, Mode = BindingMode.TwoWay });

Hope you get it :)

Steps to Reproduce

  1. Take the code below to create a nested control in another one.
  2. Add an Entry as the nested control.
  3. Try to bind the TextProperty to a stringProperty from the BindingContext.
  4. You will never Bind them in anyway (OneWay, TwoWay does not work)..

Link to public reproduction project repository

Does my sample code is enough? Let me know, Regards

Version with bug

6.0.486 (current)

Last version that worked well

Unknown/Other

Affected platforms

iOS, Android, Windows, macOS

Affected platform versions

iOS 16, Mac, Android 12

Did you find any workaround?

You will need to provide a relative Source to make it works.

Text="{Binding Source={RelativeSource AncestorType={x:Type vm:SignInViewModel}}, Path=Email, Mode=TwoWay}"/>

Relevant log output

No response

@Phenek Phenek added the t/bug Something isn't working label Sep 23, 2022
@SarthakGz
Copy link

I am not sure if this should work or not but you can always use relative bindings in that case

@Phenek
Copy link
Author

Phenek commented Sep 24, 2022

@SarthakGz for this workaround, It works!

Text="{Binding Source={RelativeSource AncestorType={x:Type vm:SignInViewModel}}, Path=Email, Mode=TwoWay}"/>

Maybe this one needs attention, Is it the correct default behavior?

PS: I know that I can Bind a color to a Shadow witout Relative Binding, so why do I have to do this with my nested input?

<Border ...>
   <Border.Shadow>
      <Shadow  Brush="{Binding ShadowBrush, Mode=OneWay}"
         Offset="0,2" 
         Radius="20" 
         Opacity="0.5" />
   </Border.Shadow>
   ...
   <Border>

@PureWeen PureWeen added the area-xaml XAML, CSS, Triggers, Behaviors label Sep 28, 2022
@PureWeen PureWeen added this to the Backlog milestone Sep 28, 2022
@ghost
Copy link

ghost commented Sep 28, 2022

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@Phenek
Copy link
Author

Phenek commented Nov 26, 2022

Hello,
Could we have a guideline about the future intended behavior of BindingContext?

  • using Source={RelativeSource AncestorType={x:Type ...}}
    is making useless the x:Datatype autocompletion
    Does it make Compiled Bindings? (Compiled bindings are resolved more quickly than classic bindings)

  • Or I can set the Binding context manually on each elements on the page and so on to their children, when Parent set and when BindingContextChanged...
    _view.BindingContext = BindingContext;

What should be the default BindingContext?

  • Null ?
  • Self ? (generaly the view it self) *
  • The closest parent BindingContext not Null ? *

*This two are really interesting, and depends if you works on MVVM or not.
Maybe x:Datatype could choose for us?

I just wanted to know which way should I take, to make less refactoring at the end.
Regards,

@Phenek Phenek changed the title [Bug] Binding on nested controls [Bug] BindingContext default behavior, on nested controls Nov 26, 2022
@AathifMahir
Copy link

This is kind a Sucks, The Intel sense does show the properties for nested controls and binds without any issue but doesn't work when app launches, On Most Cases We need to use RelativeSource or Reference Markup Extensions to Get Most of it work on Nested Controls with Compiled Bindings with Single Data Context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-xaml XAML, CSS, Triggers, Behaviors platform/android 🤖 platform/iOS 🍎 platform/macOS 🍏 macOS / Mac Catalyst platform/windows 🪟 s/triaged Issue has been reviewed t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants