How to create popup window that display Product Details ?

Kaouthar GR AOUICHAOUI 80 Reputation points
2023-10-02T14:07:46.96+00:00

Hi friends!

I have a DataGrid that contains a list of product . when i click on a product i should open a popup windows that contains Product's details and i would modify the Price in it for example.

I implement a GlobalUsing.cs such :

global using System;

global using System.ComponentModel;

global using System.Collections.ObjectModel;

global using System.Diagnostics;

global using System.Text.Json;

global using Maui.DataGrid;

global using CommunityToolkit.Maui;

global using CommunityToolkit.Maui.Views;

global using MauiApp4.Views;

global using MauiApp4.Models;

global using MauiApp4.Services;

global using Microsoft.Maui.Controls;

namespace MauiApp4;

i write that code in the page ProductList.xaml

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp4.Views.ProductList"
             xmlns:dg="clr-namespace:Maui.DataGrid;assembly=Maui.DataGrid"
             Title="Liste des Produits">


    <Grid RowDefinitions="70,*" BackgroundColor="Aquamarine">
        <Button Text="Open Popup" Clicked="Button_Clicked"/>
        <dg:DataGrid x:Name="productsCollection"
                     Grid.Row="1" 
                     ItemsSource="{Binding Products}" 
                     ItemSelected="DataGrid_ItemSelected"
                     SelectionEnabled="True"
                     SelectedItem="{Binding SelectedProduct}"
                     RowHeight="180" HeaderHeight="50"
                     PullToRefreshCommand="{Binding RefreshCommand}"
                     IsRefreshing="{Binding IsRefreshing}"
                     HeaderBackground="Red">
            <!--Datagrid empty-->
            <dg:DataGrid.NoDataView>
                <Label BackgroundColor="AliceBlue" Text="Nothing to to see here 🙈" HorizontalTextAlignment="Center" HorizontalOptions="Center" VerticalOptions="Center" />
            </dg:DataGrid.NoDataView>

            <!--Remplir la Datagrid -->
            <dg:DataGrid.Columns>
                <dg:DataGridColumn Title="Image" Width="180"  >
                    <dg:DataGridColumn.CellTemplate>
                        <DataTemplate>
                            <Image  Aspect="AspectFill">
                                <Image.Source>
                                    <UriImageSource
                                        Uri="{Binding thumbnail}"
                                        CacheValidity="00:12:00:00"
                                    />
                                </Image.Source>
                            </Image>
                        </DataTemplate>
                    </dg:DataGridColumn.CellTemplate>
                </dg:DataGridColumn>
                <dg:DataGridColumn Title="Code à Barre" PropertyName="id"  SortingEnabled="True">
              </dg:DataGridColumn>

                <dg:DataGridColumn Title="Libellé" PropertyName="title" />
                <dg:DataGridColumn Title="Prix" PropertyName="price" />
                <dg:DataGridColumn Title="Catégorie" PropertyName="category" />
                <dg:DataGridColumn Title="Marque" PropertyName="brand" />
            </dg:DataGrid.Columns>
        </dg:DataGrid>
        
    </Grid>
    
</ContentPage>

in the page productList.cs i wrote:

namespace MauiApp4.Views;

public partial class ProductList : ContentPage
{
	public ProductList()
	{
		InitializeComponent();

        // Initializing the BindingContext with Products

        BindingContext = new Models.AllProducts();

	}

    private void Button_Clicked(object sender, EventArgs e)
    {

    }

    async void DataGrid_ItemSelected(object sender, SelectionChangedEventArgs e)
    {
        if (e.CurrentSelection.Count != 0)
        {
            Product product = e.CurrentSelection.FirstOrDefault() as Product;
            var navigationParams = new Dictionary<string, object>
            {
                { "product", product }
            };

             //Open popup window and pass the product selected

            var popup = new ProductDetails();
            Product  result= await Shell.Current.CurrentPage.ShowPopupAsync(popup) as Product; 
            
            productsCollection.SelectedItem = null;
        }
    }
    
}

In the page ProductDetails.xaml defined as a popup page:

<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
               xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="MauiApp4.Views.ProductDetails"
              >
    <ScrollView BackgroundColor="#eee"  >
        <VerticalStackLayout>
             <CarouselView Loop="False"
                ItemsSource="{Binding product.images}"
                VerticalOptions="Start"
                HeightRequest="300"
                HorizontalScrollBarVisibility="Never" >
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding}"
                                Aspect="AspectFit"
                                HeightRequest="300" />
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
              <VerticalStackLayout Margin="24, 10" Spacing="10" >
                <Label Text="{Binding product.title}" FontSize="Title" FontFamily="OpenSansSemibold" />
                <Label Text="{Binding product.description}" FontSize="Body" FontFamily="OpenSansRegular" /> -->
                 <Grid ColumnDefinitions="*,*" ColumnSpacing="30" Margin="0, 10" >
                    <HorizontalStackLayout>
                        <Label Text="💵  $" FontSize="30" VerticalTextAlignment="Center" FontFamily="OpenSansRegular" />
						<!-- I can change the price of the product: -->
                        <Entry x:Name="newprice" Placeholder="Price" Text="{Binding product.price}" FontSize="40" FontFamily="OpenSansRegular" TextChanged="Entry_TextChanged" />
                    </HorizontalStackLayout>
                </Grid>
                <HorizontalStackLayout>
                    <Label Text="Brand: " FontSize="20" VerticalTextAlignment="Center" FontFamily="OpenSansRegular" />
                    <Label Text="{Binding product.brand}" FontSize="30" FontFamily="OpenSansRegular" />
                </HorizontalStackLayout>
                <HorizontalStackLayout>
                    <Label Text="Category: " FontSize="20" VerticalTextAlignment="Center" FontFamily="OpenSansRegular" />
                    <Label Text="{Binding product.category}" TextTransform="Uppercase" FontSize="30" FontFamily="OpenSansRegular" />
                </HorizontalStackLayout>
                <Button Text="Valider"  Clicked="Button_Clicked"  HorizontalOptions="CenterAndExpand"/>
            </VerticalStackLayout>
        </VerticalStackLayout>
    </ScrollView>
</toolkit:Popup>

in the page ProductDetails.cs i wrote that code :

namespace MauiApp4.Views;

[QueryProperty(nameof(Product), "product")]
public partial class ProductDetails : Popup, IQueryAttributable, INotifyPropertyChanged
{
    public Product product { get; private set; }

    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        product = query["product"] as Product;
        OnPropertyChanged("product");
    }

    public ProductDetails()
    {
        InitializeComponent();
        BindingContext = this;
        Console.WriteLine("product inside details:" + product + "BINDINGCONTEXT::" + BindingContext);
    }

    
// that line provide an error
    private void Button_Clicked(object sender, EventArgs e) => Close( new ProductDetails() { Product.price = newprice.Text });
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
2,966 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,362 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
769 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 69,311 Reputation points Microsoft Vendor
    2023-10-03T02:46:22.6033333+00:00

    Hello,

    When you select item in the dataGrid, you can transfer Product object directly with ProductDetails's constructor. After returning result, you need to set the price from returned product to the transferred product like following code.

    async void DataGrid_ItemSelected(object sender, SelectionChangedEventArgs e)
      {
          if (e.CurrentSelection.Count != 0)
          {
              Product product = e.CurrentSelection.FirstOrDefault() as Product;
    
             var popup = new ProductDetails(product);
              Product result = await Shell.Current.CurrentPage.ShowPopupAsync(popup) as Product;
              if (result != null)
              {
                  product.price = result.price;   
              }
              productsCollection.SelectedItem = null;
          }
      }
    

    Then open your ProductDetails.xaml.cs, you can get the transferred product, then set it to the local product object. As note, you need to add OnPropertyChanged method in the set product method. You can return the local product object in the close method.

    public partial class ProductDetails : Popup, INotifyPropertyChanged
    {
        private Product _product;
       public Product product
        {
            get { return _product; }
            set { _product = value; OnPropertyChanged(); }
        }
        public ProductDetails(Product product)
        {
            InitializeComponent();
            this.product = product;
            BindingContext = this;
            Console.WriteLine("product inside details:" + product + "BINDINGCONTEXT::" + BindingContext);
        }
    
      private void Button_Clicked(object sender, EventArgs e) => Close(product);
    

    By the way, if you want to Product's property changed at the runtime. You need to implement INotifyPropertyChanged as well in your Product, here is a simple property for price.

    public class Product: INotifyPropertyChanged
      {
    
    ...
    
         private string _price;
         public string price
          {
              get { return _price; }
              set { _price = value; OnPropertyChanged(); }
          }
    
         public event PropertyChangedEventHandler PropertyChanged;
    
         public void OnPropertyChanged([CallerMemberName] string name = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
      }
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful