Reputation: 31
I am new at .Net MAUI and MVVM struct. I have MainPage.xaml and DeletePage.xaml and have 1 button in both pages to fire DeleteColor method in my MainViewModel.cs by command. I can fire the DeleteColor method from the button placed in MainPage.xaml, but not from the button in DeletePage.
MainPage.xaml:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppYotubeDersi.MainPage"
xmlns:viewmodel="clr-namespace:MauiAppYotubeDersi.ViewModel"
x:DataType="viewmodel:MainViewModel"
>
<CollectionView ItemsSource="{Binding ColorItems}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:String}">
<Grid Padding="0, 4"
ColumnDefinitions=".80*,.20*">
<Frame Grid.Column="0"
Grid.RowSpan="2">
<Label Text="{Binding .}"
x:Name="lbl_colorName"
FontSize="Medium">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" >
</TapGestureRecognizer>
</Label.GestureRecognizers>
</Label>
</Frame>
<Button x:Name="btn2"
Grid.Column="1"
Text="X"
BackgroundColor="Red"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteColorCommand}"
CommandParameter="{Binding .}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
DeletePage.xaml:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp.DeletePage"
xmlns:viewmodel="clr-namespace:MauiApp.ViewModel"
x:DataType="viewmodel:MainViewModel"
Title="DeleteColor">
<VerticalStackLayout>
<Entry x:Name="ent_DeleteColor"
VerticalOptions="Center"
HorizontalOptions="Center"
Text="a"
/>
<Button x:Name="btn"
Text="X"
Command="{Binding DeleteColorCommand}"
CommandParameter="{Binding Source={x:Reference ent_DeleteColor}, Path=Text}"/>
</VerticalStackLayout>
</ContentPage>
MainViewModel.cs:
public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
string color;
[ObservableProperty]
ObservableCollection<string> colorItems;
public MainViewModel()
{
ColorItems = new ObservableCollection<string>();
}
[RelayCommand]
void DeleteColor(string color)
{
if (colorItems.Contains(color))
{
ColorItems.Remove(color);
Color = string.Empty;
}
}
}
Upvotes: 0
Views: 248
Reputation: 4332
Well, according to your comments, as a wiki answer:
Setting BindingContext
for DeletePage can fix the problem.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp.DeletePage"
xmlns:viewmodel="clr-namespace:MauiApp.ViewModel"
x:DataType="viewmodel:MainViewModel"
Title="DeleteColor">
<ContentPage.BindingContext>
<viewmodel:MainViewModel/>
</ContentPage.BindingContext>
or
public DeletePage()
{
InitializeComponent();
BindingContext = new MainViewModel();
}
It's worth mentioning that if you want to keep only one instance of the MainViewModel for the entire duration of the program, you can use dependency injection (MAUI is already built-in). Like this:
In MauiProgram.cs:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.Services.AddSingleton<MainViewModel>()
.AddTransient<MainPage>()
.AddTransient<DeletePage>();
........
And set BindingContext for pages:
public MainPage(MainViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
public DeletePage(MainViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
Upvotes: 0