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;
}
CodePudding user response:
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://docs.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!