Listviews of Products and users

This commit is contained in:
2025-08-21 17:18:35 +02:00
parent 1649eaa992
commit 543b9c2aaf
13 changed files with 358 additions and 41 deletions

View File

@ -99,6 +99,9 @@
<MauiXaml Update="Views\ProductDetailView.xaml"> <MauiXaml Update="Views\ProductDetailView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Views\ProductListView.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Views\UserDetailView.xaml"> <MauiXaml Update="Views\UserDetailView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>

View File

@ -19,8 +19,8 @@
Route="UserListView" /> Route="UserListView" />
<ShellContent <ShellContent
Title="Products" Title="Products"
ContentTemplate="{DataTemplate views:ProductDetailView}" ContentTemplate="{DataTemplate views:ProductListView}"
Route="ProductDetailView" /> Route="ProductListView" />
<ShellContent <ShellContent
Title="Customerss" Title="Customerss"
ContentTemplate="{DataTemplate views:CustomerDetailView}" ContentTemplate="{DataTemplate views:CustomerDetailView}"

View File

@ -0,0 +1,26 @@
using AdventureWorks.EntityLayer;
using AdventureWorks.ViewModelLayer.ViewModelClasses;
using Common.Library;
namespace AdventureWorks.MAUI.CommandClasses
{
public class ProductViewModelCommands : ProductViewModel
{
#region Constructors
public ProductViewModelCommands() : base()
{
}
public ProductViewModelCommands(IRepository<Product> repo) : base(repo)
{
}
#endregion
public void LoadProducts()
{
Get();
}
public void LoadProductById(int id)
{
ProductObject = Get(id);
}
}
}

View File

@ -0,0 +1,53 @@
using AdventureWorks.EntityLayer;
using AdventureWorks.ViewModelLayer;
using Common.Library;
using System.Windows.Input;
namespace AdventureWorks.MAUI.CommandClasses;
public class UserViewModelCommands : UserViewModel
{
#region constructors
public UserViewModelCommands() : base()
{
}
public UserViewModelCommands(IRepository<User> repo) : base(repo)
{
}
public UserViewModelCommands(IRepository<User> repo, IRepository<PhoneType> phoneRepo) : base(repo, phoneRepo)
{
}
#endregion
#region Private Variables
private bool _IsSaveCommandEnabled = true;
#endregion
#region Public Properties
public bool IsSaveCommandEnabled
{
get { return _IsSaveCommandEnabled; }
set
{
_IsSaveCommandEnabled = value;
RaisePropertyChanged(nameof(IsSaveCommandEnabled));
}
}
#endregion
#region Commands
public ICommand SaveCommand { get; private set; }
#endregion
#region Init Method
public override void Init()
{
base.Init();
SaveCommand = new Command(() => Save(), () => IsSaveCommandEnabled);
}
#endregion
}

View File

@ -1,7 +1,7 @@
using AdventureWorks.DataLayer; using AdventureWorks.DataLayer;
using AdventureWorks.EntityLayer; using AdventureWorks.EntityLayer;
using AdventureWorks.MAUI.CommandClasses;
using AdventureWorks.MAUI.Views; using AdventureWorks.MAUI.Views;
using AdventureWorks.ViewModelLayer;
using Common.Library; using Common.Library;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -27,9 +27,17 @@ namespace AdventureWorks.MAUI
builder.Services.AddScoped<IRepository<User>, UserRepository>(); builder.Services.AddScoped<IRepository<User>, UserRepository>();
builder.Services.AddScoped<IRepository<EntityLayer.Color>, ColorRepository>(); builder.Services.AddScoped<IRepository<EntityLayer.Color>, ColorRepository>();
builder.Services.AddScoped<IRepository<PhoneType>, PhoneTypeRepository>(); builder.Services.AddScoped<IRepository<PhoneType>, PhoneTypeRepository>();
builder.Services.AddScoped<UserViewModel>();
builder.Services.AddScoped<UserViewModelCommands>();
builder.Services.AddScoped<UserDetailView>(); builder.Services.AddScoped<UserDetailView>();
#if WINDOWS builder.Services.AddScoped<UserListView>();
builder.Services.AddScoped<IRepository<Product>, ProductRepository>();
builder.Services.AddScoped<ProductViewModelCommands>();
builder.Services.AddScoped<ProductDetailView>();
builder.Services.AddScoped<ProductListView>();
#if XWINDOWS
SetWindowOptions(builder); SetWindowOptions(builder);
SetWindowHandlers(); SetWindowHandlers();
#endif #endif

View File

@ -0,0 +1,49 @@
<?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="AdventureWorks.MAUI.Views.ProductListView"
xmlns:partial="clr-namespace:AdventureWorks.MAUI.ViewsPartial"
xmlns:vm="clr-namespace:AdventureWorks.MAUI.CommandClasses"
xmlns:model="clr-namespace:AdventureWorks.EntityLayer;assembly=AdventureWorks.EntityLayer"
x:DataType="vm:ProductViewModelCommands"
Title="ProductListView">
<Border Style="{StaticResource Screen.Border}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<partial:HeaderView ViewTitle="Product List"
ViewDescription="The list of products in the system"/>
<CollectionView Grid.Row="1"
SelectionMode="Single"
ItemsSource="{Binding ProductList}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Product">
<Border Margin="8" Padding="12" >
<VerticalStackLayout Spacing="4">
<HorizontalStackLayout>
<Label FontAttributes="Bold"
FontSize="Title"
Text="{Binding Name}" />
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="Color:" />
<Label Text="{Binding Color}" />
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="Price:" />
<Label Text="{Binding ListPrice, StringFormat='{0:C}'}" />
</HorizontalStackLayout>
<HorizontalStackLayout>
<Button Text="Edit" />
<Button Text="Delete" />
</HorizontalStackLayout>
</VerticalStackLayout>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</Border>
</ContentPage>

View File

@ -0,0 +1,24 @@
using AdventureWorks.MAUI.CommandClasses;
namespace AdventureWorks.MAUI.Views;
public partial class ProductListView : ContentPage
{
public ProductListView(ProductViewModelCommands viewModel)
{
InitializeComponent();
ViewModel = viewModel;
}
private readonly ProductViewModelCommands ViewModel;
protected override void OnAppearing()
{
base.OnAppearing();
BindingContext = ViewModel;
ViewModel.Get();
}
}

View File

@ -4,8 +4,8 @@
x:Class="AdventureWorks.MAUI.Views.UserDetailView" x:Class="AdventureWorks.MAUI.Views.UserDetailView"
xmlns:partial="clr-namespace:AdventureWorks.MAUI.ViewsPartial" xmlns:partial="clr-namespace:AdventureWorks.MAUI.ViewsPartial"
xmlns:converters="clr-namespace:AdventureWorks.MAUI.Converters" xmlns:converters="clr-namespace:AdventureWorks.MAUI.Converters"
xmlns:vm="clr-namespace:AdventureWorks.ViewModelLayer;assembly=AdventureWorks.ViewModelLayer" xmlns:vm="clr-namespace:AdventureWorks.MAUI.CommandClasses"
x:DataType="vm:UserViewModel" x:DataType="vm:UserViewModelCommands"
Title="User Information"> Title="User Information">
<ContentPage.Resources> <ContentPage.Resources>
@ -64,7 +64,9 @@
<Entry Grid.Row="4" <Entry Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Text="{Binding UserObject.Email}" /> Text="{Binding UserObject.Email}" />
<Label Grid.Row="5" Text="Is Enrolled ?"/>
<Label Grid.Row="5"
Text="Is Enrolled?" />
<FlexLayout Grid.Row="5" <FlexLayout Grid.Row="5"
Grid.Column="1" Grid.Column="1"
@ -107,7 +109,8 @@
</HorizontalStackLayout> </HorizontalStackLayout>
<HorizontalStackLayout> <HorizontalStackLayout>
<Label Text="Part-Time" /> <Label Text="Part-Time" />
<RadioButton GroupName="EmployeeType" IsChecked="{Binding UserObject.IsFullTime, Converter={StaticResource invertedBoolean}}"/> <RadioButton IsChecked="{Binding UserObject.IsFullTime, Converter={StaticResource invertedBoolean}}"
GroupName="EmployeeType" />
</HorizontalStackLayout> </HorizontalStackLayout>
</FlexLayout> </FlexLayout>
@ -146,7 +149,8 @@
<HorizontalStackLayout Grid.Row="12" <HorizontalStackLayout Grid.Row="12"
Grid.Column="1" Grid.Column="1"
Spacing="5"> Spacing="5">
<Button Text="Save" Clicked="SaveButton_Clicked"/> <Button Text="Save"
Command="{Binding SaveCommand}"/>
<Button Text="Cancel" /> <Button Text="Cancel" />
</HorizontalStackLayout> </HorizontalStackLayout>
</Grid> </Grid>

View File

@ -1,15 +1,16 @@
using AdventureWorks.ViewModelLayer; using AdventureWorks.MAUI.CommandClasses;
namespace AdventureWorks.MAUI.Views; namespace AdventureWorks.MAUI.Views;
public partial class UserDetailView : ContentPage public partial class UserDetailView : ContentPage
{ {
public UserDetailView(UserViewModel viewModel) public UserDetailView(UserViewModelCommands viewModel)
{ {
InitializeComponent(); InitializeComponent();
ViewModel = viewModel; ViewModel = viewModel;
} }
public UserViewModel ViewModel { get; set; } public UserViewModelCommands ViewModel { get; set; }
protected override void OnAppearing() protected override void OnAppearing()
{ {
@ -21,8 +22,5 @@ public partial class UserDetailView : ContentPage
ViewModel.Get(1); // Assuming you want to get the user with ID 1 ViewModel.Get(1); // Assuming you want to get the user with ID 1
} }
private void SaveButton_Clicked(object sender, EventArgs e)
{
System.Diagnostics.Debugger.Break();
}
} }

View File

@ -1,16 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:partial="clr-namespace:AdventureWorks.MAUI.ViewsPartial"
xmlns:vm="clr-namespace:AdventureWorks.MAUI.CommandClasses"
xmlns:model="clr-namespace:AdventureWorks.EntityLayer;assembly=AdventureWorks.EntityLayer"
x:Class="AdventureWorks.MAUI.Views.UserListView" x:Class="AdventureWorks.MAUI.Views.UserListView"
x:DataType="vm:UserViewModelCommands"
Title="User List"> Title="User List">
<VerticalStackLayout VerticalOptions="Center"
HorizontalOptions="Center" <Border Style="{StaticResource Screen.Border}">
Spacing="10"> <Grid>
<Label <Grid.RowDefinitions>
Text="User List" <RowDefinition Height="Auto" />
FontSize="Header" <RowDefinition Height="*" />
HorizontalOptions="Center" /> </Grid.RowDefinitions>
<Button Text="Navigate to Detali" <partial:HeaderView ViewTitle="User List"
Clicked="NavigateToDetail_Clicked" /> ViewDescription="Use this Screen to view and manage users." />
<ListView Grid.Row="1"
ItemsSource="{Binding UserList}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:User">
<ViewCell>
<Border Margin="8"
Padding="12">
<VerticalStackLayout Spacing="4">
<HorizontalStackLayout>
<Label FontAttributes="Bold"
FontSize="Title"
Text="{Binding LastNameFirstName}" />
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="Email" />
<Label Text="{Binding Email}" />
</HorizontalStackLayout>
<HorizontalStackLayout>
<Button Text="Edit" />
<Button Text="Delete" />
</HorizontalStackLayout>
</VerticalStackLayout> </VerticalStackLayout>
</Border>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Border>
</ContentPage> </ContentPage>

View File

@ -1,10 +1,22 @@
using AdventureWorks.MAUI.CommandClasses;
namespace AdventureWorks.MAUI.Views; namespace AdventureWorks.MAUI.Views;
public partial class UserListView : ContentPage public partial class UserListView : ContentPage
{ {
public UserListView() public UserListView(UserViewModelCommands viewModel)
{ {
InitializeComponent(); InitializeComponent();
ViewModel = viewModel;
}
private readonly UserViewModelCommands ViewModel;
protected override void OnAppearing()
{
base.OnAppearing();
BindingContext = ViewModel;
ViewModel.Get();
} }
private async void NavigateToDetail_Clicked(object sender, EventArgs e) private async void NavigateToDetail_Clicked(object sender, EventArgs e)

View File

@ -0,0 +1,91 @@
using AdventureWorks.EntityLayer;
using Common.Library;
using System.Collections.ObjectModel;
namespace AdventureWorks.ViewModelLayer.ViewModelClasses;
public class ProductViewModel : ViewModelBase
{
#region Constructors
public ProductViewModel() : base()
{
}
public ProductViewModel(IRepository<Product> repo) : base()
{
Repository = repo;
}
#endregion
#region Private Variables
private Product? _ProductObject = new();
private ObservableCollection<Product> _ProductList = new();
private readonly IRepository<Product>? Repository;
#endregion
#region Public Properties
public Product? ProductObject
{
get { return _ProductObject; }
set
{
_ProductObject = value;
RaisePropertyChanged(nameof(ProductObject));
}
}
public ObservableCollection<Product> ProductList
{
get { return _ProductList; }
set
{
_ProductList = value;
RaisePropertyChanged(nameof(ProductList));
}
}
#endregion
public ObservableCollection<Product> Get()
{
if (Repository != null)
{
ProductList = new ObservableCollection<Product>(Repository.Get());
}
return ProductList;
}
public Product Get(int id)
{
try
{
if (Repository != null)
{
ProductObject = Repository.Get(id);
}
else
{
ProductObject = new Product
{
ProductID = id,
Name = "A new product",
Color = "Black",
StandardCost = 10,
ListPrice = 20,
SellStartDate = Convert.ToDateTime("2020-10-15"),
Size = "LG"
};
}
}
catch (Exception)
{
throw;
}
return ProductObject;
}
public bool Save()
{
throw new NotImplementedException("Save method is not implemented yet.");
}
}

View File

@ -25,6 +25,7 @@ public class UserViewModel : ViewModelBase
#region Private Variables #region Private Variables
private User? _UserObject = new(); private User? _UserObject = new();
private ObservableCollection<User> _UserList = new();
private readonly IRepository<User>? Repository; private readonly IRepository<User>? Repository;
private readonly IRepository<PhoneType>? _PhoneTypeRepository; private readonly IRepository<PhoneType>? _PhoneTypeRepository;
private ObservableCollection<string> _PhoneTypesList = new(); private ObservableCollection<string> _PhoneTypesList = new();
@ -43,6 +44,16 @@ public class UserViewModel : ViewModelBase
} }
public ObservableCollection<User> UserList
{
get { return _UserList; }
set
{
_UserList = value;
RaisePropertyChanged(nameof(UserList));
}
}
public ObservableCollection<string> PhoneTypesList public ObservableCollection<string> PhoneTypesList
{ {
get { return _PhoneTypesList; } get { return _PhoneTypesList; }
@ -59,6 +70,11 @@ public class UserViewModel : ViewModelBase
#region Get Method #region Get Method
public ObservableCollection<User> Get() public ObservableCollection<User> Get()
{ {
if (Repository != null)
{
UserList = new ObservableCollection<User>(Repository.Get());
}
return new(); return new();
} }