XAML 自定义BindableProperty上的绑定不起作用

agyaoht7  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(203)

I'm having trouble binding a value to a custom ContentView I made.
My MainPage uses CustomFrameView which is a ContentView .
My CustomFrameView has a string BindableProperty . This works fine when I manually enter a string, but fails when I try to use Binding. And I'm sure the binding should work because it works when used on a Label .
Anyone has an idea on why it does not work?

MainPage.xaml

<StackLayout> 
    <!-- DOES work -->
          <Label Text="{Binding Name}"/>
    <!-- DOES work-->
          <controls:CustomFrameView TestName="Test456"/>
    <!-- DOES NOT work-->
          <controls:CustomFrameView TestName="{Binding Name}"/>
        </StackLayout>

MainPage.xaml.cs

public MainPage()
    {
        InitializeComponent();

        BindingContext = new MainPageViewModel();
    }

MainPageViewModel.cs

public partial class MainPageViewModel : ObservableObject
    {
        [ObservableProperty]
        private string name;
    
        public MainPageViewModel ()
        {
            Name = "Test123";
        }
    }

CustomFrameView.xaml.cs

public partial class CustomFrameView : ContentView
    {
    public string TestName
        {
            get => (string)GetValue(TestNameProperty);
            set => SetValue(TestNameProperty, value);
        }
    
        public static readonly BindableProperty TestNameProperty =
            BindableProperty.Create(
                nameof(TestName),
                typeof(string),
                typeof(CustomFrameView),
                "",
                propertyChanged: SetTestNameProperty);
    
    
        private static void SetTestNameProperty(BindableObject bindable, object oldValue, object newValue)
        {     
            var vm = bindable.BindingContext as CustomFrameViewModel;
            vm.TestName = (string) newValue;
        }
    
        public CustomFrameView()
        {
            InitializeComponent();
            this.BindingContext = new CustomFrameViewModel();
        }
    }

CustomFrameViewModel.cs

public partial class CustomFrameViewModel : ObservableObject
    {
        [ObservableProperty]
        private string testName;
    }

nnsrf1az

nnsrf1az1#

It's simple actually, the reason it does not work is that you are setting a different binding context to your control itself. It usually uses its parent's view's BC. Your Controls are your views and they don't have separate ViewModels. You can brush up on your MVVM here: https://learn.microsoft.com/en-us/dotnet/maui/xaml/fundamentals/mvvm
I recommend you change the following:
In your Custom control you go something like this:

public partial class CustomFrameView : ContentView
    {
    public string TestName
        {
            get => (string)GetValue(TestNameProperty);
            set => SetValue(TestNameProperty, value);
        }
    
        public static readonly BindableProperty TestNameProperty =
            BindableProperty.Create(
                nameof(TestName),
                typeof(string),
                typeof(CustomFrameView),
                string.Empty;
                );
    
    
        public CustomFrameView()
        {
            InitializeComponent();
        }
    }

Dump your Custom Control VM and then see if this works out for you.
Also if you are using Maui you can check out my custom controls if you wanna learn how to do them properly : https://github.com/FreakyAli/MAUI.FreakyControls
Good luck!

相关问题