Reputation: 30388
I'm trying to create a reusable ContentView
in my .NET MAUI app that needs to call a method in parent's view model.
Something like this:
<ContentPage
xmlns:vm="MyApp.ViewModels"
xmlns:control="MyApp.Views.Controls"
x:DataType="vm:MyViewModel">
<Grid
RowDefinitions="50,50, *">
<control:MyContentView Grid.Row="0" />
...
</Grid>
</ContentPage>
Here's the ContentView
code:
<ContentView
xmlns:model="MyApp.Models.MyModel">
<Button
Text="Do Something"
Command="{Binding DoSomethingCommand} />
</ContentView>
Here's the ViewModel
code:
public partial class MyViewModel : BaseViewModel
{
...
[RelayCommand]
async Task DoSomething()
{
// Business logic here...
}
}
Two questions:
ContentView
?ContentView
reusable, I want to be able to use it in another ContentPage
which will have its own view model. I can make sure the method names match but is it possible to not tightly couple the binding for the Button
in the ContentView
with a specific view model?Upvotes: 2
Views: 3699
Reputation: 13803
How do I call the method in parent content page's view model from the ContentView?
One problem, one thread. I will answer the first problem.
You can add a Bindable Property in your ContentView. Let's say your view is named ChildView
.
Then you can refer to the following code:
ChildView.xaml
Here, TestControlView
is the x:Name
property of current ContentView.
<?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="MauiContentViewApp.ChildView"
x:Name="TestControlView">
<VerticalStackLayout>
<Button Text="Do Something"
Command="{Binding Source={x:Reference TestControlView}, Path= ChildCommand}" />
</VerticalStackLayout>
</ContentView>
ChildView.xaml.cs
public partial class ChildView : ContentView
{
// add ChildCommandProperty here
public static readonly BindableProperty ChildCommandProperty =
BindableProperty.Create(nameof(ChildCommand), typeof(ICommand), typeof(ChildView));
public ICommand ChildCommand
{
get => (ICommand)GetValue(ChildCommandProperty);
set => SetValue(ChildCommandProperty, value);
}
public ChildView()
{
InitializeComponent();
}
}
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"
xmlns:mauiapp="clr-namespace:MauiContentViewApp"
x:Class="MauiContentViewApp.MainPage"
x:Name="mainpage">
<ContentPage.BindingContext>
<mauiapp:MyViewModel></mauiapp:MyViewModel>
</ContentPage.BindingContext>
<ScrollView>
<VerticalStackLayout>
<mauiapp:ChildView
ChildCommand="{Binding DoSomethingCommand}" >
</mauiapp:ChildView>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
MyViewModel.cs
public class MyViewModel
{
public ICommand DoSomethingCommand => new Command(doSomethingMethod);
private void doSomethingMethod(object obj)
{
System.Diagnostics.Debug.Write("invoke command dosomething");
}
}
Upvotes: 2