maui
maui copied to clipboard
[Bug] BindingContext default behavior, on nested controls
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
- Take the code below to create a nested control in another one.
- Add an Entry as the nested control.
- Try to bind the TextProperty to a stringProperty from the BindingContext.
- 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
I am not sure if this should work or not but you can always use relative bindings in that case
@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>
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.
Hello, Could we have a guideline about the future intended behavior of BindingContext?
-
using
Source={RelativeSource AncestorType={x:Type ...}}
is making useless thex: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,
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