Can a Bindable property in a ContentView be of type Func<bool>
? That is, something like this:
public partial class MyControl : ContentView
{
public static readonly BindableProperty DoSomethingProperty = BindableProperty.Create(
nameof(DoSomething),
typeof(Func<bool>),
typeof(MyControl);
public Func<bool> DoSomething
{
get => (Func<bool>)GetValue(DoSomethingProperty);
set => SetValue(DoSomethingProperty, value);
}
}
Then you could use it in a page like such:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:MauiPlayground.Controls"
x:DataType="vm:MainPageViewModel"
x:Class="MauiPlayground.MainPage">
<ContentPage.Content>
<VerticalStackLayout>
<controls:MyControl DoSomething="{Binding ViewModelDoSomething}" />
</VerticalStackLayout>
</ContentPage.Content>
</ContentPage>
And the MainPageViewModel would contain this method:
public bool ViewModelSoSomething()
{
return true;
}
(This isn't actual code, just wondering if this can be done in theory. If, for example, you want to pass a callback function or method to the ContentView)
I tried doing something like this and the compiler didn't complain, but the value of the DoSomething property was never set. Maybe there's another way of doing this?
You can achieve this by adding BindableProperty
of type ICommand
to your ContentView
and you can also pass data to the command by adding BindableProperty
of type object
.
I achieved this function on my side,And I also added a common property YourName
to my ContentView.
Please refer to the following code:
MyControl.xaml
public partial class MyControl : ContentView
{
public String YourName
{
get
{
String value = (String)GetValue(YourNameProperty);
return value;
}
set
{
SetValue(YourNameProperty, value);
}
}
public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
, typeof(String)
, typeof(MyControl), defaultBindingMode: BindingMode.TwoWay, propertyChanged: OnYourNameChanged);
static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
{
Console.WriteLine("-----------------> " + newValue);
}
// add BindableProperty:ChildCommandProperty
public static readonly BindableProperty ChildCommandProperty =
BindableProperty.Create(nameof(ChildCommand), typeof(ICommand), typeof(MyControl));
public ICommand ChildCommand
{
get => (ICommand)GetValue(ChildCommandProperty);
set => SetValue(ChildCommandProperty, value);
}
// add BindableProperty:ChildCommandParameterProperty
public static BindableProperty ChildCommandParameterProperty =
BindableProperty.Create(nameof(ChildCommandParameter), typeof(object), typeof(MyControl));
public object ChildCommandParameter
{
get => (object)GetValue(ChildCommandParameterProperty);
set => SetValue(ChildCommandParameterProperty, value);
}
public MyControl()
{
InitializeComponent();
}
}
MyControl.xaml.cs
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiMyContentViewApp.Controls.MyControl"
x:Name="TestControlView"
>
<ContentView.Content>
<VerticalStackLayout>
<Label Text="{Binding Source={x:Reference TestControlView}, Path=YourName}" x:Name="NameLabel" Margin="10"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Button Text="Do Something"
Command="{Binding Source={x:Reference TestControlView}, Path= ChildCommand}"
CommandParameter="{Binding Source={x:Reference TestControlView}, Path= ChildCommandParameter}"
/>
</VerticalStackLayout>
</ContentView.Content>
</ContentView>
Usage example:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiMyContentViewApp.MainPage"
xmlns:controls="clr-namespace:MauiMyContentViewApp.Controls"
xmlns:viewmodels="clr-namespace:MauiMyContentViewApp.ViewModels"
x:Name="mainpage"
>
<ContentPage.BindingContext>
<viewmodels:TestViewModel></viewmodels:TestViewModel>
</ContentPage.BindingContext>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<controls:MyControl BackgroundColor="Yellow" YourName="HanMeimei"
ChildCommand="{Binding DoSomethingCommand}"
ChildCommandParameter = "test123"
>
</controls:MyControl>
</VerticalStackLayout>
</ContentPage>
TestViewModel.cs
public class TestViewModel
{
public ICommand DoSomethingCommand => new Command(doSomethingMethod);
private void doSomethingMethod(object obj)
{
System.Diagnostics.Debug.Write("----->do something and the passed parameter is : " + obj.ToString());
}
}