diff --git a/src/Controls/src/Core/ContentPresenter.cs b/src/Controls/src/Core/ContentPresenter.cs index 012bfc565082..783b8dd72997 100644 --- a/src/Controls/src/Core/ContentPresenter.cs +++ b/src/Controls/src/Core/ContentPresenter.cs @@ -104,7 +104,7 @@ protected override LayoutConstraint ComputeConstraintForView(View view) internal override void SetChildInheritedBindingContext(Element child, object context) { - // We never want to use the standard inheritance mechanism, we will get this set by our parent + SetInheritedBindingContext(child, context); } static async void OnContentChanged(BindableObject bindable, object oldValue, object newValue) diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue23797.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue23797.cs new file mode 100644 index 000000000000..c43dccd3b3e6 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue23797.cs @@ -0,0 +1,115 @@ +using System.ComponentModel; +using System.Windows.Input; +using Microsoft.Maui.Controls; + +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 23797, "Binding context in ContentPresenter", PlatformAffected.All)] +public class Issue23797 : ContentPage +{ + public static Issue23797_ViewModel Issue23797_ViewModel { get; } = new Issue23797_ViewModel(); + + public Issue23797() + { + Title = "Issue23797"; + + var stackLayout = new StackLayout + { + Spacing = 20, + Padding = 20 + }; + + var label = new Label + { + FontSize = 16, + BackgroundColor = Colors.LightGray, + Padding = 10, + AutomationId = "CurrentMessageLabel" + }; + label.SetBinding(Label.TextProperty, new Binding("Message", source: Issue23797_ViewModel)); + stackLayout.Children.Add(label); + + var customControl = new CustomControlWithCustomContent_Issue23797 + { + BindingContext = Issue23797_ViewModel + }; + + var button = new Button + { + Text = "Click to change to 'success'", + BackgroundColor = Colors.LightBlue, + AutomationId = "Issue23797Btn" + }; + button.SetBinding(Button.CommandProperty, new Binding("TestCommand")); + + customControl.MyContent = button; + stackLayout.Children.Add(customControl); + + Content = stackLayout; + } +} + +public class CustomControlWithCustomContent_Issue23797 : ContentView +{ + public static readonly BindableProperty MyContentProperty = BindableProperty.Create( + nameof(MyContent), + typeof(View), + typeof(CustomControlWithCustomContent_Issue23797), + null); + + public View MyContent + { + get => (View)GetValue(MyContentProperty); + set => SetValue(MyContentProperty, value); + } + + public CustomControlWithCustomContent_Issue23797() + { + ControlTemplate = new ControlTemplate(() => + { + var border = new Border + { + Stroke = Colors.Red, + StrokeThickness = 2, + Padding = 10 + }; + + var contentPresenter = new ContentPresenter(); + contentPresenter.SetBinding(ContentPresenter.ContentProperty, new Binding(nameof(MyContent), source: RelativeBindingSource.TemplatedParent)); + + border.Content = contentPresenter; + return border; + }); + } +} + +public class Issue23797_ViewModel : INotifyPropertyChanged +{ + private string _message = "failure"; + + public string Message + { + get => _message; + set + { + _message = value; + OnPropertyChanged(); + } + } + + public ICommand TestCommand { get; } + + public Issue23797_ViewModel() + { + TestCommand = new Command(() => + { + Message = "success"; + }); + } + + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23797.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23797.cs new file mode 100644 index 000000000000..2ea4ce1f30c4 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23797.cs @@ -0,0 +1,24 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue23797 : _IssuesUITest +{ + public Issue23797(TestDevice testDevice) : base(testDevice) + { + } + + public override string Issue => "Binding context in ContentPresenter"; + + [Test] + [Category(UITestCategories.Layout)] + public void ContentPresenterShouldPropagateBindingContextForTemplateBindings() + { + App.WaitForElement("Issue23797Btn"); + App.Tap("Issue23797Btn"); + var messageAfterClick = App.WaitForElement("CurrentMessageLabel").GetText(); + Assert.That(messageAfterClick, Is.EqualTo("success")); + } +} \ No newline at end of file