simsenVejle
Well-known member
- Joined
- Feb 14, 2021
- Messages
- 46
- Programming Experience
- Beginner
Hi,
I am in the process of going through a youtube series with VPF and MVVM and here I have discovered a bug that I can not figure out. to solve
I open a page where there are 3 labels 3 textboxes 4 buttons. Id, Name and Age and then a grid showing an Employee (= my own name) which is hard coded.
One button is Add. When I add the first time, it goes well. Now there are 2 employes in the gridview Anja and then Bob (which I just added).
Then the error comes when I then add one or more employee - then it changes Bob (and the next inserted employee) Lise with Lises name Id and Age. So the first row (can't remember what such a row is called) is displayed correctly (with the name Anja), while the subsequent rows get the last row I have inserted data.
I suspect it is in EmployeeViewModel that there is a problem and here specifically when I run between CurrentEmployee and objEmployee but I am unfortunately not good enough to figure out what to change and where so I hope someone of you can help me.
The zip file is to big, so I cann't upload. Please let me know an email adress to send the zip files. Below I will copy the files.
If you are missing something more than the code shown below, please let me know.
Best regards
Simsen
Models.Employees
------------------
Models.EmployeeService
----------------------
Commands.RelayCommand
-----------------------
Views.EmployeeView
---------------------
ViewModels.EmployeeViewModel
I am in the process of going through a youtube series with VPF and MVVM and here I have discovered a bug that I can not figure out. to solve
I open a page where there are 3 labels 3 textboxes 4 buttons. Id, Name and Age and then a grid showing an Employee (= my own name) which is hard coded.
One button is Add. When I add the first time, it goes well. Now there are 2 employes in the gridview Anja and then Bob (which I just added).
Then the error comes when I then add one or more employee - then it changes Bob (and the next inserted employee) Lise with Lises name Id and Age. So the first row (can't remember what such a row is called) is displayed correctly (with the name Anja), while the subsequent rows get the last row I have inserted data.
I suspect it is in EmployeeViewModel that there is a problem and here specifically when I run between CurrentEmployee and objEmployee but I am unfortunately not good enough to figure out what to change and where so I hope someone of you can help me.
The zip file is to big, so I cann't upload. Please let me know an email adress to send the zip files. Below I will copy the files.
If you are missing something more than the code shown below, please let me know.
Best regards
Simsen
Models.Employees
Models.Employees:
Models.Employees
namespace MvvmDemo.Models
{
public class Employee : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private int id;
public int Id
{
get => id;
set { id = value; OnPropertyChanged("Id"); }
}
private string name;
public string Name
{
get { return name; }
set { name = value; OnPropertyChanged("Name"); }
}
private int age;
public int Age
{
get { return age; }
set { age = value; OnPropertyChanged("Age"); }
}
}
}
Models.EmployeeService
Models.EmployeeService:
Models.EmployeeService (her kommer et senere spørgsmål, altså hvis jeg kan få det her til at virke)
namespace MvvmDemo.Models
{
public class EmployeeService
{
private static List<Employee> ObjEmployeesList;
public EmployeeService()
{
ObjEmployeesList = new List<Employee>()
{
new Employee { Id=101, Name="Anja", Age=55 }
};
}
public List<Employee> GetAll()
{
return ObjEmployeesList;
}
public bool Add(Employee objNewEmployee)
{
//Age must be between 21 and 58
if (objNewEmployee.Age < 21 || objNewEmployee.Age > 58)
throw new ArgumentException("Invalid Age limit for Employee");
ObjEmployeesList.Add(objNewEmployee);
return true;
}
public bool Update (Employee objEmployeeToUpdate)
{
bool IsUpdated = false;
for (int index = 0; index <ObjEmployeesList.Count; index++)
{
if (ObjEmployeesList[index].Id==objEmployeeToUpdate.Id)
{
ObjEmployeesList[index].Name = objEmployeeToUpdate.Name;
ObjEmployeesList[index].Age = objEmployeeToUpdate.Age;
IsUpdated = true;
break;
}
}
return IsUpdated;
}
public bool Delete (int id)
{
bool IsDeleted = false;
for (int index = 0; index < ObjEmployeesList.Count; index++)
{
if (ObjEmployeesList[index].Id == id)
{
ObjEmployeesList.RemoveAt(index);
IsDeleted = true;
break;
}
}
return IsDeleted;
}
public Employee Search(int id)
{
return ObjEmployeesList.FirstOrDefault(e => e.Id == id);
}
}
}
Commands.RelayCommand
Commands.RelayCommand:
namespace MvvmDemo.Commands
{
public class RelayCommand : ICommand
{
public event EventHandler CanExecuteChanged;
private readonly Action DoWork;
public RelayCommand(Action work)
{
DoWork = work;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
DoWork();
}
}
}
Views.EmployeeView
Views.EmployeeView:
Views.EmployeeView
<UserControl x:Class="MvvmDemo.Views.EmployeeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MvvmDemo.Views"
mc:Ignorable="d">
<Grid Margin="15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<!--Row 0-->
<TextBlock Text="Employee Management" Grid.Row="0" Grid.Column="0"
Grid.ColumnSpan="2" FontSize="20" FontWeight="Bold"
HorizontalAlignment="Center" Margin="5,8" Padding="3"/>
<!--Row 1-->
<TextBlock Text="Enter Id" Grid.Row="1" Grid.Column="0" />
<TextBox x:Name="txtId" Grid.Row="1" Grid.Column="1" Margin="5,8"
Padding="3" Text="{Binding Path=CurrentEmployee.Id, Mode=TwoWay}" />
<!--Row 2-->
<TextBlock Text="Enter Name" Grid.Row="2" Grid.Column="0" />
<TextBox x:Name="txtName" Grid.Row="2" Grid.Column="1" Margin="5,8" Padding="3"
Text="{Binding Path=CurrentEmployee.Name, Mode=TwoWay}"/>
<!--Row 3-->
<TextBlock Text="Enter Age" Grid.Row="3" Grid.Column="0" />
<TextBox x:Name="txtAge" Grid.Row="3" Grid.Column="1" Margin="5,8" Padding="3"
Text="{Binding Path=CurrentEmployee.Age, Mode=TwoWay}"/>
<!--Row 4-->
<StackPanel Orientation="Horizontal" Grid.Row="4" Grid.Column="1">
<Button x:Name="btnAdd" Content="Add" Margin="5,8" Padding="3"
Command="{Binding Path=SaveCommand}"/>
<Button x:Name="btnSearch" Content="Search" Margin="5,8" Padding="3"
Command="{Binding Path=SearchCommand}"/>
<Button x:Name="btnUpdate" Content="Update" Margin="5,8" Padding="3" />
<Button x:Name="btnDelete" Content="Delete" Margin="5,8" Padding="3" />
</StackPanel>
<!--Row 5-->
<TextBlock x:Name="txtMessage" Grid.Column="1" Grid.Row="5" Margin="5,8" Padding="3"
Text="{Binding Path=Message}"/>
<!--Row 6-->
<DataGrid Name="dgEmployees" AutoGenerateColumns="False" Grid.Row="6" Grid.Column="1"
Margin="5,8" Padding="3" ItemsSource="{Binding Path=EmployeeList, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="Employee Id" Width="auto" Binding="{Binding Path=Id}" />
<DataGridTextColumn Header="Employee Name" Width="auto" Binding="{Binding Path=Name}" />
<DataGridTextColumn Header="Employee Age" Width="auto" Binding="{Binding Path=Age}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
ViewModels.EmployeeViewModel
ViewModels.EmployeeViewModel:
namespace MvvmDemo.ViewModels
{
public class EmployeeViewModel : INotifyPropertyChanged
{
#region INotifyPropertyChanged_Implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
readonly EmployeeService ObjEmployeeService;
public EmployeeViewModel()
{
ObjEmployeeService = new EmployeeService();
LoadData();
CurrentEmployee = new Employee();
saveCommand = new RelayCommand(Save);
searchCommand = new RelayCommand(Search);
}
#region DisplayOperation
private ObservableCollection<Employee> employeeList;
public ObservableCollection<Employee> EmployeeList
{
get { return employeeList; }
set { employeeList = value; OnPropertyChanged("EmployeeList"); }
}
private void LoadData()
{
EmployeeList = new ObservableCollection<Employee>(ObjEmployeeService.GetAll());
}
#endregion
private Employee currentEmployee;
public Employee CurrentEmployee
{
get { return currentEmployee; }
set { currentEmployee = value; OnPropertyChanged("CurrentEmployee"); }
}
private readonly RelayCommand saveCommand;
private string message;
public string Message
{
get { return message; }
set { message = value; OnPropertyChanged("Message"); }
}
#region SaveOperation
public RelayCommand SaveCommand
{
get { return saveCommand; }
}
public void Save()
{
try
{
var isSaved = ObjEmployeeService.Add(CurrentEmployee);
LoadData();
if (isSaved)
Message = "Employee saved";
else
Message = "Save operation failed";
}
catch (Exception ex)
{
Message = ex.Message;
}
}
#endregion
#region Search Operation
private readonly RelayCommand searchCommand;
public RelayCommand SearchCommand
{
get { return searchCommand; }
}
public void Search()
{
try
{
var objEmployee = ObjEmployeeService.Search(CurrentEmployee.Id);
if (objEmployee != null)
{
CurrentEmployee.Name = objEmployee.Name;
CurrentEmployee.Age = objEmployee.Age;
}
else
{
Message = "Employee Not found";
}
}
catch (Exception ex)
{
Message = ex.Message;
}
}
#endregion
}
}