I have to make a WPF App to add, delete and update Items for Client Management purposes. I have so far been able to add and remove the items to the List using MVVM but I am unable to update the selected items. I require help in this regard.
The code for the project is as follows:
Details Class.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment_2.Model
{
public class Details :INotifyPropertyChanged
{
private string name;
public string Name
{ get { return name; } set { name = value; OnPropertyChanged(Name); } }
private string company;
public string Company
{ get { return company; } set { company = value; OnPropertyChanged(Company); } }
private string region;
public string Region
{ get { return region; } set { region = value; OnPropertyChanged(Region); } }
private string hra;
public string HRA
{
get { return hra; }
set
{
hra = value;
OnPropertyChanged(HRA);
}
}
private string basic;
public string Basic
{ get { return basic; }
set { basic = value;
OnPropertyChanged(Basic);
}
}
private string pf;
public string PF
{ get { return pf; }
set
{
pf = value;
OnPropertyChanged(PF);
}
}
private string salary;
public string Salary
{ get { return salary; }
set
{
salary = value;
OnPropertyChanged(Salary);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string det)
{
PropertyChangedEventHandler pc = PropertyChanged;
if (pc != null)
pc(this, new PropertyChangedEventArgs(det));
}
}
}
DetailsViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Assignment_2.Commands;
using Assignment_2.Model;
namespace Assignment_2.ViewModel
{
public class DetailsViewModel : INotifyPropertyChanged
{
private Details record;
public Details Record
{
get { return record; }
set { record = value; NotifyPropertyChanged("Record"); }
}
private ObservableCollection<Details> records;
public ObservableCollection<Details> Records
{
get { return records; }
set { records = value; } // NotifyPropertyChanged("Records");
}
private ICommand _SubmitCommand;
public ICommand SubmitCommand
{
get
{
if (_SubmitCommand == null)
{
_SubmitCommand = new RelayCommand(SubmitExecute, CanSubmitExecute, false);
}
return _SubmitCommand;
}
}
public DetailsViewModel()
{
Record = new Details();
Records = new ObservableCollection<Details>();
}
private void SubmitExecute(object parameter)
{
var TempRecord = new Details();
//TempRecord = Record;
TempRecord.Name = Record.Name;
TempRecord.Company = Record.Company;
TempRecord.Region = Record.Region;
TempRecord.HRA = Record.HRA;
TempRecord.Salary = Record.Salary;
TempRecord.Basic = Record.Basic;
TempRecord.PF = Record.PF;
Records.Add(TempRecord);
}
private bool CanSubmitExecute(object parameter)
{
if (string.IsNullOrEmpty(Record.Name) || string.IsNullOrEmpty(Record.Company))
{
return false;
}
else
{
return true;
}
}
private ICommand _SubmitCommand1;
public ICommand SubmitCommand1
{
get
{
if (_SubmitCommand1 == null)
{
_SubmitCommand1 = new RelayCommand(SubmitExecute1, CanSubmitExecute1, false);
}
return _SubmitCommand1;
}
}
public int findIndex(Details myDetails)
{
int count = 0;
for (int i = 0; i < Records.Count; i++)
{
count = 0;
Details myRecord = Records[i];
if (myRecord.Name == myDetails.Name)
count++;
else continue;
if (myRecord.Company == myDetails.Company)
count++;
else continue;
if (myRecord.Region == myDetails.Region)
count++;
else continue;
if (myRecord.Salary == myDetails.Salary)
count++;
else continue;
if (myRecord.HRA == myDetails.HRA)
count++;
else continue;
if (myRecord.Basic == myDetails.Basic)
count++;
else continue;
if (myRecord.PF == myDetails.PF)
count++;
else continue;
if (count == 7)
return i;
}
return -1;
}
private void SubmitExecute1(object parameter)
{
Records.Remove((Details)parameter);
}
private bool CanSubmitExecute1(object parameter)
{
if (string.IsNullOrEmpty(Record.Name) || string.IsNullOrEmpty(Record.Company))
{
return false;
}
else
{
return true;
}
}
private ICommand _SubmitCommand2;
public ICommand SubmitCommand2
{
get
{
if (_SubmitCommand2 == null)
{
_SubmitCommand2 = new RelayCommand(SubmitExecute2, CanSubmitExecute2, false);
}
return _SubmitCommand2;
}
}
private void SubmitExecute2(object parameter)
{
}
private bool CanSubmitExecute2(object parameter)
{
if (string.IsNullOrEmpty(Record.Name) || string.IsNullOrEmpty(Record.Company))
{
return false;
}
else
{
return true;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string de)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(de));
}
}
}
RelayCommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Assignment_2.Commands
{
class RelayCommand : ICommand
{
Action<object> executeAction;
Func<object, bool> canExecute;
bool canExecuteCache;
public RelayCommand(Action<object> executeAction, Func<object, bool> canExecute, bool canExecuteCache)
{
this.canExecute = canExecute;
this.executeAction = executeAction;
canExecuteCache = canExecuteCache;
}
public bool CanExecute(object parameter)
{
if (canExecute == null)
{
return true;
}
else
{
return canExecute(parameter);
}
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public void Execute(object parameter)
{
executeAction(parameter);
}
}
}
MainWindow.xaml
<Window x:Class="Assignment_2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Assignment_2.ViewModel"
Title="MainWindow" Height="401" Width="472">
<Window.Resources>
<vm:DetailsViewModel x:Key="DetailsViewModel"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource DetailsViewModel}}" RenderTransformOrigin="0.5,0.5" Margin="0,0,1,1">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-0.21"/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20.59"/>
<RowDefinition Height="22.906"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="29*"/>
<RowDefinition Height="293*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text=" Name" HorizontalAlignment="Center" Margin="0,0,0,4" Grid.RowSpan="2" Width="35" />
<TextBox Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Name,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="2,0,0,1" Grid.RowSpan="2"/>
<TextBlock Text="Company" HorizontalAlignment="Center" Margin="0,2,0,3" Width="51" Grid.RowSpan="2" Grid.Row="1"/>
<TextBox Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Company,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="2,2,0,1" Grid.Row="1"/>
<TextBlock Grid.Row="2" Text="Region" HorizontalAlignment="Center" Margin="0,1,0,4" Width="37"/>
<TextBox Grid.Row="2" Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Region,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="3,1,0,4"/>
<TextBlock Grid.Column="1" Text="HRA" HorizontalAlignment="Left" Margin="131,-1,0,2" Width="23"/>
<TextBox Grid.Column="1" Width="83" HorizontalAlignment="Left" Text="{Binding Record.HRA,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="162,0,0,1"/>
<TextBlock Grid.Column="1" Text="Basic" HorizontalAlignment="Left" Margin="129,2,0,13" Width="26" Grid.RowSpan="2" Grid.Row="1"/>
<TextBox Grid.Column="1" Width="81" HorizontalAlignment="Left" Text="{Binding Record.Basic,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="162,2,0,3" Grid.Row="1"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="PF" HorizontalAlignment="Left" Margin="144,1,0,5" Width="12"/>
<TextBox Grid.Row="2" Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.PF,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="162,2,0,1"/>
<TextBlock Grid.Column="1" Text="Salary" HorizontalAlignment="Left" Margin="268,-1,0,1" Width="36"/>
<TextBox Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Salary,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="304,0,0,21" Grid.RowSpan="2"/>
<Button Content="Add" Command="{Binding SubmitCommand }" HorizontalAlignment="Left" Grid.Row="4" Margin="121,4,0,5" Width="44" Grid.Column="1"/>
<ListView x:Name="ListedView" ItemsSource="{Binding Records}" Width="Auto" Grid.Row="5" Margin="38,3,13,36" Grid.ColumnSpan="2">
<ListView.View >
<GridView >
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="Auto" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="Auto"/>
<GridViewColumn Header="Region" DisplayMemberBinding="{Binding Region}" Width="Auto" />
<GridViewColumn Header="HRA" DisplayMemberBinding="{Binding HRA}" Width="Auto" />
<GridViewColumn Header="Basic" DisplayMemberBinding="{Binding Basic}" Width="Auto" />
<GridViewColumn Header="PF" DisplayMemberBinding="{Binding PF}" Width="Auto" />
<GridViewColumn Header="Salary" DisplayMemberBinding="{Binding Salary}" Width="Auto" />
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Remove" Margin="1,36,50,150" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListView},Path=DataContext.SubmitCommand1}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Any help is appreciated in this regard. Thanks
If I understand your issue correctly, you should bind the SelectedItem property of the ListView to be able to edit the currently selected item in the TextBox elements above the ListView:
<ListView SelectedItem="{Binding Record}" ... />
With or without Binding you can do it like this :
if ((sender as ListView).SelectedValue != null)
{
string item = (sender as ListView).SelectedValue.ToString();
SelectedIndex = (sender as ListView).SelectedIndex;
list.Items[SelectedIndex] = "Updated";
}
(I like to add a ContextMenu on my ListViewItems so it is easier for users to modify the specified clicked item) :
<ListView x:Name="list">
<ListView.ContextMenu>
<ContextMenu x:Name="contextmenu">
<MenuItem x:Name="Add" Header="Add" Click="Add_Click"/>
<MenuItem x:Name="Del" Header="Delete" Click="Del_Click"/>
<MenuItem x:Name="Update" Header="Update" Click="Update_Click"/>
</ContextMenu>
</ListView.ContextMenu>
</ListView>
Related
Okay, so I wanna clear the text in my textbox with a click from a button. Both are placed within the first stackpanel in the XAML code. I'm trying to make it work with commands and bindings, but I just can't seem to make it work.. Any suggestions? SqlQueryCommand is bound to the clear button, SqlQueryString is bound to the textbox.
Vievmodel:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using WpfMVVM.Commands;
namespace PoC.ViewModels
{
class MainWindowViewModel
{
public RelayCommand ClearSqlQueryCommand { get; private set; }
public RelayCommand ClearFilterCommand { get; private set; }
public RelayCommand ClearFilterByIdCommand { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
private string sqlQueryString;
private string filterString;
private string filterByIdString;
public string SqlQueryString
{
get
{
return sqlQueryString;
}
set
{
sqlQueryString = value;
OnPropertyChanged(nameof(SqlQueryString));
}
}
public string FilterString
{
get
{
return filterString;
}
set
{
filterString = value;
OnPropertyChanged(nameof(FilterString));
}
}
public string FilterByIdString
{
get
{
return filterByIdString;
}
set
{
filterByIdString = value;
OnPropertyChanged(nameof(FilterByIdString));
}
}
public MainWindowViewModel()
{
ClearSqlQueryCommand = new RelayCommand(ClearSqlQuery, CanClearSqlQuery);
ClearFilterCommand = new RelayCommand(ClearFilter, CanClearFilter);
ClearFilterByIdCommand = new RelayCommand(ClearFilterById, CanClearFilterById);
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public void ClearSqlQuery(object parameter)
{
SqlQueryString = string.Empty;
}
public bool CanClearSqlQuery(object parameter)
{
return true;
}
public void ClearFilter(object parameter)
{
}
public bool CanClearFilter(object parameter)
{
return true;
}
public void ClearFilterById(object parameter)
{
}
public bool CanClearFilterById(object parameter)
{
return true;
}
}
}
RelayCommand:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;
namespace WpfMVVM.Commands
{
public class RelayCommand : ICommand
{
Action<object> _execute;
Func<object, bool> _canExecute;
public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute != null)
{
return _canExecute(parameter);
}
else
{
return false;
}
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
XAML:
<Window x:Class="PoC.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PoC"
xmlns:viewModels="clr-namespace:PoC.ViewModels"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<viewModels:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<TreeView>
</TreeView>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="1*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderThickness="0 0 0 1" BorderBrush="Black"/>
<StackPanel Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBox Text="{Binding SqlQueryString, UpdateSourceTrigger=PropertyChanged}" Height="30" Width="450" TextAlignment="Center"/>
<Button Content="Execute" Margin="10 0" Padding="5 0"/>
<Button Content="Clear" Padding="5 0" Command="{Binding ClearSqlQueryCommand}"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBox Text="{Binding FilterString}" Grid.Row="0" Height="30" Width="200"/>
<Button Content="Filter" Margin="10 0" Padding="5 0"/>
<Button Content="Clear" Padding="5 0" Margin="0 0 115 0"/>
<TextBox Text="{Binding FilterByIdString}" Grid.Row="0" Height="30" Width="100"/>
<Button Content="Filter" Margin="10 0 0 0" Padding="5 0"/>
</StackPanel>
<DataGrid Grid.Row="2" VerticalScrollBarVisibility="Visible" BorderThickness="0 1 1 1"/>
</Grid>
</Grid>
You seem to be missing : INotifyPropertyChangedon the MainWindowViewModelclass.
You can easily do that by setting its value to "".
texbox.Text="";
hi i have 3 folders in project namely Model,View, View Model. I moved my Xaml to View folder. My solution gets build properly buy when i run it shows the Error "cannot locate the source Userregistration.xaml".
Heres is my complete code
i have added themy folder structure for the reference. please help me i m not able to figure out this issue.
View
<Window x:Class="MVVMDemo.UserRegistrationView"
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:viewmodel="clr-namespace:MVVMDemo"
Title="Registration Window" Height="300" Width="575.851">
<Window.Resources>
<viewmodel:ViewModel x:Key="ViewModel"/>
<viewmodel:DatetimeToDateConverter x:Key="MyConverter"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource ViewModel}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Name" HorizontalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" Width="100" HorizontalAlignment="Center" Text="{Binding Student.Name, Mode=TwoWay}" Margin="76,0"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Age" HorizontalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Width="100" HorizontalAlignment="Center" Text="{Binding Student.Age, Mode=TwoWay}"/>
<Button Content="Submit" Command="{Binding SubmitCommand}" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="0"/>
<ComboBox Grid.Column="1" ItemsSource="{Binding FillCourseId}" Name="cmb_CourseIDName" HorizontalAlignment="Left" Margin="164.191,5,0,0"
Grid.Row="3" VerticalAlignment="Top" Width="168.342" Grid.RowSpan="2" DataContext="{Binding Source={StaticResource ViewModel}}" FontSize="8" IsReadOnly="True"
SelectedValue="{Binding Student.SCourseIDName,Mode=TwoWay}" RenderTransformOrigin="1.431,0.77">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Path=CourseName, Mode=TwoWay}" FontSize="12"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding Path=CourseID, Mode=TwoWay}" FontSize="12"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ListView ItemsSource="{Binding Students}" Grid.Row="4" Grid.Column="1" Margin="62.551,0,78.762,76.829"
ScrollViewer.CanContentScroll="False"
ScrollViewer.VerticalScrollBarVisibility="Visible" Height="85.152" VerticalAlignment="Bottom">
<ListView.View >
<GridView >
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="60"/>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="60"/>
<GridViewColumn Header="Joining Date" DisplayMemberBinding="{Binding JoiningDate, Converter={StaticResource MyConverter}}" Width="80" />
<GridViewColumn Header="Course Name" DisplayMemberBinding="{Binding SCourseIDName.CourseName}" Width="80"/>
<GridViewColumn Header="CourseId" DisplayMemberBinding="{Binding SCourseIDName.CourseID}" Width="60"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MVVMDemo
{
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Course { get; set; }
public DateTime JoiningDate { get; set; }
public string CourseName { get; set; }
public string CourseID { get; set; }
public Student SCourseIDName { get; set; }
}
}
ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.Data.SqlClient;
using System.Data;
using System.ComponentModel;
namespace MVVMDemo
{
public class ViewModel : ViewModelBase
{
static String connectionString = #"Data Source=RITESH-PC\SQLEXPRESS;Initial Catalog=SIT_Ritesh_DB;Integrated Security=True;";
SqlConnection con;
SqlCommand cmd;
private Student _student;
private ObservableCollection<Student> _students;
private ICommand _SubmitCommand;
public Student Student
{
get
{
return _student;
}
set
{
_student = value;
NotifyPropertyChanged("Student");
}
}
private ObservableCollection<Student> _fillCourseId = new ObservableCollection<Student>();
public ObservableCollection<Student> FillCourseId
{
get { return _fillCourseId; }
set
{
_fillCourseId = value;
OnPropertyChanged("SystemStatusData");
}
}
public ObservableCollection<Student> Students
{
get
{
return _students;
}
set
{
_students = value;
NotifyPropertyChanged("Students");
}
}
private Student _selectedcourseIdname;
public Student SelectedCourseIdName
{
get { return _selectedcourseIdname; }
set
{
_selectedcourseIdname = value;
OnPropertyChanged("SelectedCourseIdName");
}
}
public string SelectedCourseId
{
get { return _selectedcourseIdname.CourseID; }
set
{
_selectedcourseIdname.CourseID = value;
OnPropertyChanged("SelectedCourseId");
}
}
public string SelectedCourseName
{
get { return _selectedcourseIdname.CourseName; }
set
{
_selectedcourseIdname.CourseName = value;
OnPropertyChanged("SelectedCourseName");
}
}
public ICommand SubmitCommand
{
get
{
if (_SubmitCommand == null)
{
_SubmitCommand = new RelayCommand(param => this.Submit(),
null);
}
return _SubmitCommand;
}
}
//********************************************* Functions*******************************************//
public void GetCourseIdFromDB()
{
try
{
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("select * from dev_Course", con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adapter.Fill(dt);
// Student Student = new Student();
for (int i = 0; i < dt.Rows.Count; ++i)
FillCourseId.Add(new Student
{
CourseID = dt.Rows[i][0].ToString(),
CourseName = dt.Rows[i][2].ToString()
});
}
catch (Exception ex)
{
}
}
public ViewModel()
{
Student = new Student();
Students = new ObservableCollection<Student>();
Students.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Students_CollectionChanged);
GetCourseIdFromDB();
}
void Students_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged("Students");
}
private void Submit()
{
Student.JoiningDate = DateTime.Today.Date;
//Students.Add(SelectedCourseIdName);
Students.Add(Student);
Student = new Student();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyname)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyname));
}
}
}
DateTimeConverter
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Windows.Data;
namespace MVVMDemo
{
public class DatetimeToDateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DateTime date = (DateTime)value;
return date.ToString("MM/d/yyyy");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace MVVMDemo
{
public class ViewModelBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
you need to change it in the app.xmal in the line of the StartupUri
that he will be contact to the xmal in the View
example:
in the app.xmal file
<Application x:Class="UserRegistration.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UserRegistration"
StartupUri="View/UserRegistrationView.xaml">
<Application.Resources>
</Application.Resources>
You need to edit app.xaml to point to the correct view file (including the folder name in the path) which in your case is the UserRegistrationView.Xaml. The app.xaml is responsible for starting your app not to view xaml code.
The folder name may not be required. I use Resharper which creates a namespace for each folder within a project in visual studio.
I have 3 text boxes and when user enter value in them and press save button then they should add the data they contain to the data grid.
Every thing works fine and binding to the textboxes and button is done well but i do not understand how to update datagrid using the value user entered in textboxes.
My full code is here :
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" Grid.Row="0" Text="{Binding TextName}" Height="20" Width="80" HorizontalAlignment="Center"></TextBox>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding RollNumber}" Height="20" Width="80"></TextBox>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Class}" Height="20" Width="80"></TextBox>
<Label Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">Name</Label>
<Label Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">RollNumber</Label>
<Label Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center">Class</Label>
</Grid>
<Grid Grid.Row="1" >
<Button Width="80" Height="20" Command="{Binding SaveStudentRecord}"> Save</Button>
</Grid>
<Grid Grid.Row="2">
<DataGrid ItemsSource="{Binding DGrid}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding DgName}" Width="150"></DataGridTextColumn>
<DataGridTextColumn Header="Rollnumber" Binding="{Binding dgRollnumber}" Width="150"></DataGridTextColumn>
<DataGridTextColumn Header="Class" Binding="{Binding dgClass}" Width="150"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Grid>
</Window>
ViewModel is:
class ViewModel
{
private string textName;
private string rollNumber;
private string cclass;
private RelayCommand saveStudentRecord;
private Model editModel;
public string TextName
{
get { return textName; }
set
{
textName = value;
PropertyChangedEventArgs("TextName");
}
}
public string RollNumber
{
get { return rollNumber; }
set
{
rollNumber = value;
PropertyChangedEventArgs("RollNumber");
}
}
public string Class
{
get { return cclass; }
set
{
rollNumber = value;
PropertyChangedEventArgs("Class");
}
}
public bool canExecute { get; set; }
public Model EditModel
{
get
{
return editModel ;
}
set
{
editModel = value;
PropertyChangedEventArgs("EditModel");
}
}
public ViewModel()
{
canExecute = true;
}
public RelayCommand SaveStudentRecord
{
get { return saveStudentRecord = new RelayCommand(() => MyAction(), canExecute); }
}
private void MyAction()
{
string chck1 = TextName; //I see on debugging that TextName contains the text entered so how to add this text to Datagrid column
string chck2 = Class;
string chck3 = RollNumber;
// How to add this data to datagrid
MessageBox.Show("Hii");
}
public event PropertyChangedEventHandler PropertyChanged;
private void PropertyChangedEventArgs(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
What exactly i mean is how to bind the datagrid inside the MyAction() such that all the three textbox strings will be added to the respective columns ?
As others have suggested in comments I'm not sure what Dgrid represents, but I think a simple example should help:
This is just a window with a DataGrid, TextBox and a button. When you type something in the datagrid and press the button it adds the value to the datagrid. It's done MVVM, I hope this demonstrates the process.
(.NET 4.6 syntax. If it doesn't work change the observable collection and move the creation of it to the constructor)
MainView.xaml
<Window x:Class="WpfApplication4.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainView" Height="350" Width="525">
<Grid>
<DataGrid HorizontalAlignment="Left" Height="207" Margin="103,46,0,0" VerticalAlignment="Top" Width="311" ItemsSource="{Binding Stuff}" AutoGenerateColumns="false">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding}"/>
</DataGrid.Columns>
</DataGrid>
<TextBox HorizontalAlignment="Left" Height="20" Margin="167,9,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="179" Text="{Binding TextValue, Mode=TwoWay}"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="351,8,0,0" VerticalAlignment="Top" Width="75" Command="{Binding GoCommand}"/>
</Grid>
</Window>
MainViewModel.cs
using System.Collections.ObjectModel;
using System.Windows.Input;
namespace WpfApplication4
{
public class MainViewModel
{
public ObservableCollection<string> Stuff { get; set; } = new ObservableCollection<string>();
public ICommand GoCommand { get; set; }
public string TextValue { get; set; }
public MainViewModel()
{
Stuff.Add("a");
Stuff.Add("b");
Stuff.Add("c");
Stuff.Add("d");
GoCommand = new RelayCommand((p) => Stuff.Add(TextValue));
}
}
}
MainView.xaml.cs
using System.Windows;
namespace WpfApplication4
{
public partial class MainView : Window
{
public MainView()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
}
RelayCommand.cs
using System;
using System.Diagnostics;
using System.Windows.Input;
namespace WpfApplication4
{
public class RelayCommand : ICommand
{
private readonly Action<object> execute;
private readonly Predicate<object> canExecute;
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null) throw new ArgumentNullException("execute");
this.execute = execute;
this.canExecute = canExecute;
}
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return canExecute == null || canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
execute(parameter);
}
}
}
I am new in MVVM, in this small app i have a listbox ,three textboxes and two buttons one is Update and another is Add. In the XAML i have done binding of all listbox columns with textboxes, according to command my update button functions properly when i change values in either of textboxes but i am not aware how to take values from textboxes and add values in collection by using command .
Here is the Xaml code.
<Grid Height="314">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="ListViewEmployeeDetails" Grid.Row="1" Margin="4,109,12,23" ItemsSource="{Binding Products}" >
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" Width="100"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="100" />
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price}" Width="100" />
</GridView>
</ListView.View>
</ListView>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtID" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewEmployeeDetails,Path=SelectedItem.ID}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewEmployeeDetails,Path=SelectedItem.Name}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,61,0,0" Name="txtPrice" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewEmployeeDetails,Path=SelectedItem.Price}" />
<Label Content="ID" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
<Label Content="Price" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,59,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />
<Button Content="Update" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="311,59,0,0" Name="btnUpdate"
VerticalAlignment="Top" Width="141"
Command="{Binding Path=UpdateCommad}"
/>
<Button Content="Add" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="311,17,0,0" Name="btnAdd"
VerticalAlignment="Top" Width="141"
Command="{Binding UpdateCommad}"
/>
</Grid>
And here is the Product class
public class Product : INotifyPropertyChanged
{
private int m_ID;
private string m_Name;
private double m_Price;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public int ID
{
get
{
return m_ID;
}
set
{
m_ID = value;
OnPropertyChanged("ID");
}
}
public string Name
{
get
{
return m_Name;
}
set
{
m_Name = value;
OnPropertyChanged("Name");
}
}
public double Price
{
get
{
return m_Price;
}
set
{
m_Price = value;
OnPropertyChanged("Price");
}
}
}
here is the ViewModel Class, now i am statically adding product into m_Products.
class ProductViewModel
{
private ObservableCollection<Product> m_Products;
public ProductViewModel()
{
m_Products = new ObservableCollection<Product>
{
new Product {ID=1, Name ="Pro1", Price=10},
new Product{ID=2, Name="BAse2", Price=12}
};
}
public ObservableCollection<Product> Products
{
get
{
return m_Products;
}
set
{
m_Products = value;
}
}
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
}
set
{
mUpdater = value;
}
}
private ICommand addUpdater;
public ICommand AddCommand
{
get
{
if (addUpdater == null)
addUpdater = new Updater();
return addUpdater;
}
set
{
addUpdater = value;
}
}
private class Updater : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
#endregion
}
}
Now i dont know how to add values(Product) into collection by using command on Add button click.
You can use the relay command. It allows you to inject the command's logic via delegates passed into its constructor:
/// <summary>
/// Class representing a command sent by a button in the UI, defines what to launch when the command is called
/// </summary>
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
//[DebuggerStepThrough]
/// <summary>
/// Defines if the current command can be executed or not
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
With this type of command its very easy do what you want, for example in your viewmodel you can do this now:
public class ProductViewModel : INotifyPropertyChanged
{
private ObservableCollection<Product> m_Products;
public ProductViewModel()
{
m_Products = new ObservableCollection<Product>
{
new Product {ID = 1, Name = "Pro1", Price = 10},
new Product {ID = 2, Name = "BAse2", Price = 12}
};
}
private Product _selectedProduct;
public Product SelectedProduct
{
get
{
return _selectedProduct;
}
set
{
_selectedProduct = value;
OnPropertyChanged("SelectedProduct");
}
}
public ObservableCollection<Product> Products
{
get
{
return m_Products;
}
set
{
m_Products = value;
}
}
ICommand _addCommand;
public ICommand AddCommand
{
get
{
if (_addCommand == null)
{
_addCommand = new RelayCommand(param => AddItem());
}
return _addCommand;
}
}
ICommand _deleteCommand;
public ICommand DeleteCommand
{
get
{
if (_deleteCommand == null)
{
_deleteCommand = new RelayCommand(param => DeleteItem((Product)param));
}
return _deleteCommand;
}
}
private void DeleteItem(Product product)
{
if (m_Products.Contains(product))
{
m_Products.Remove(product);
}
}
private void AddItem()
{
m_Products.Add(new Product());
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
As you can see, there are two commands, one to add a Product and other to delete the selected product.You don't have to worry about the update, you are using an ObservableCollection<>.Also, I add the property selectedProduct to your ViewModel to know what element was selected in your view:
<Grid Height="314">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="ListViewEmployeeDetails" Grid.Row="1" Margin="4,109,12,23" ItemsSource="{Binding Products}" SelectedValue="{Binding SelectedProduct}" >
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" Width="100" />
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="100" />
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price}" Width="100" />
</GridView>
</ListView.View>
</ListView>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtID" VerticalAlignment="Top" Width="178" Text="{Binding SelectedProduct.ID}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtName" VerticalAlignment="Top" Width="178" Text="{Binding SelectedProduct.Name}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,61,0,0" Name="txtPrice" VerticalAlignment="Top" Width="178" Text="{Binding SelectedProduct.Price}" />
<Label Content="ID" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
<Label Content="Price" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,59,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />
<Button Content="Remove" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="311,59,0,0" Name="btnUpdate"
VerticalAlignment="Top" Width="141"
Command="{Binding DeleteCommand}" CommandParameter="{Binding SelectedProduct}"
/>
<Button Content="Add" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="311,17,0,0" Name="btnAdd"
VerticalAlignment="Top" Width="141"
Command="{Binding AddCommand}"
/>
</Grid>
In the delete button I declare the CommandParamameter and I bound it to the SelectedProduct property. This is the param that receive the RelayCommand to delete a product. It is no necessary, you have already in the viewmodel the SelectedProduct, but I did it anyway to show how you can pass a parameter to a command.
[EDIT 1]
To achieve the behavior that you want you need to add three new properties in your viewModel (Id, Name, and Price).Now those properties should be bounded with TextBoxes. To edit a selected product in your ListView, in the set of the SelectedProduct property you need to set too the values of the ID, Name and Prices properties. You have to set the properties of the selected product when a textbox change its value too.
Changes in the ViewModel:
private int _id=1;
public int Id
{
get
{
return _id;
}
set
{
_id = value;
if (SelectedProduct!=null)
{
SelectedProduct.ID = _id;
}
OnPropertyChanged("Id");
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
if (SelectedProduct != null)
{
SelectedProduct.Name = _name;
}
OnPropertyChanged("Name");
}
}
private double _price = 0;
public double Price
{
get
{
return _price;
}
set
{
_price = value;
if (SelectedProduct != null)
{
SelectedProduct.Price = _price;
}
OnPropertyChanged("Price");
}
}
private Product _selectedProduct;
public Product SelectedProduct
{
get
{
return _selectedProduct;
}
set
{
_selectedProduct = value;
Id = _selectedProduct != null ? _selectedProduct.ID : 0;
Name = _selectedProduct != null ? _selectedProduct.Name : "";
Price = _selectedProduct != null ? _selectedProduct.Price : 0;
OnPropertyChanged("SelectedProduct");
}
}
Changes in your View:
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtID" VerticalAlignment="Top" Width="178" Text="{Binding Id}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtName" VerticalAlignment="Top" Width="178" Text="{Binding Name}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,61,0,0" Name="txtPrice" VerticalAlignment="Top" Width="178" Text="{Binding Price}" />
I an trying to get skills on WPF with MVVM pattern. i almost complete form with basic features but facing 2 problems
1) My Gridview Change Event not firing
2) How to refresh the grid after Inserting Record
My ViewModel and View code is given below
View Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using DatabaseLayer;
using System.Data;
namespace WPFnMVVM.ViewModel
{
public class ContactsViewModel : WPFnMVVM.Common.VMBase
{
#region Variables
private int _Id;
private string _First_Name;
private string _Last_Name;
private DateTime _DOB;
private clstbl_Contacts _Contacts;
public WPFnMVVM.Common.RelayCommand _addCommand;
public DataTable _tblContacts;
#endregion
public ContactsViewModel()
{
_tblContacts = LoadContacts();
}
#region Public Properties
public int Id
{
get { return _Id; }
set { _Id = value; OnPropertyChanged("Id"); }
}
public string First_Name
{
get { return _First_Name; }
set { _First_Name = value; OnPropertyChanged("First_Name"); }
}
public string Last_Name
{
get { return _Last_Name; }
set { _Last_Name = value; OnPropertyChanged("Last_Name"); }
}
public DateTime DOB
{
get { return _DOB; }
set { _DOB = value; OnPropertyChanged("DOB"); }
}
public clstbl_Contacts Contacts
{
get { return _Contacts; }
set
{
_Contacts = value;
OnPropertyChanged("Contacts");
}
}
public DataTable ContactsList
{
get { return _tblContacts; }
set
{
_tblContacts = value;
OnPropertyChanged("ContactsList");
}
}
#endregion
#region Private Methods
private DataTable LoadContacts()
{
clstbl_Contacts objContact = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
{
return objContact.Select();
};
}
private void AddContacts()
{
clstbl_Contacts objContacts = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
objContacts.First_Name = First_Name;
objContacts.Last_Name = Last_Name;
objContacts.DOB = DOB;
objContacts.Insert();
}
#endregion
#region Commands
public ICommand AddCommand
{
get
{
if (_addCommand == null)
{
_addCommand = new WPFnMVVM.Common.RelayCommand(
param => this.AddContacts(),
param => true
);
}
return _addCommand;
}
}
#endregion
}
}
View
<Window x:Class="WPFnMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:WPFnMVVM.ViewModel"
xmlns:View="clr-namespace:WPFnMVVM"
Title="MainWindow" Height="350" Width="337">
<Window.DataContext>
<VM:ContactsViewModel/>
</Window.DataContext>
<Grid Name="MyGrid">
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,13,0,0" TextWrapping="Wrap" Text="{Binding Path=First_Name, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,47,0,0" TextWrapping="Wrap" Text="{Binding Path=Last_Name, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<Label Content="First Name" HorizontalAlignment="Left" Margin="8,10,0,0" VerticalAlignment="Top"/>
<Label Content="Last Name" HorizontalAlignment="Left" Margin="9,47,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<Label Content="DOB" HorizontalAlignment="Left" Margin="8,75,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<DatePicker Height="25" HorizontalAlignment="Left" Margin="95,76,0,0" Name="datePicker1"
VerticalAlignment="Top" Width="120" SelectedDate="{Binding Path=DOB, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="9,118,0,0" VerticalAlignment="Top" Width="75" Command="{Binding Path=AddCommand}"/>
<Button Content="Update" HorizontalAlignment="Left" Margin="102,118,0,0" VerticalAlignment="Top" Width="75"/>
<Button Content="Delete" HorizontalAlignment="Left" Margin="193,118,0,0" VerticalAlignment="Top" Width="75"/>
<ListView BorderBrush="White" ItemsSource="{Binding Path=ContactsList, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" Margin="11,156,10,10" SelectedValue="{Binding Path=Contacts, UpdateSourceTrigger=PropertyChanged}">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name"
DisplayMemberBinding="{Binding Path=First_Name}" Width="70" />
<GridViewColumn Header="Last Name"
DisplayMemberBinding="{Binding Path=Last_Name}" Width="70" />
<GridViewColumn Header="DOB"
DisplayMemberBinding="{Binding Path=DOB}" Width="70" />
</GridView>
</ListView.View>
</ListView >
</Grid>
</Window>
Please guide and also give me ref of any practical application with sql crud functions if possible from which i can enhance my skills.
Thanks
DataTable does not implement INotifyPropertyChanged, so you will have issues binding directly to it. You'll see the initial data but then changes to the data will not be reflected in the view.
I'd say the easiest alternative is to use a DataView, which does implement INotifyPropertyChanged. You can easily get a view for your table by using _tblContacts.DefaultView.
#Rob H , I change my logic a bit a good think is now i am getting my values and record also inserting but now the only problem is gridview is not refreshing after insertionof record.
please view a code below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using DatabaseLayer;
using System.Data;
namespace WPFnMVVM.ViewModel
{
public class ContactsViewModel : WPFnMVVM.Common.VMBase
{
#region Variables
private int _Id;
private string _First_Name;
private string _Last_Name;
private DateTime _DOB;
private clstbl_Contacts _Contacts;
public WPFnMVVM.Common.RelayCommand _addCommand;
public ObservableCollection<clstbl_Contacts> _ContactsList;
#endregion
#region Contructor
public ContactsViewModel()
{
LoadContacts();
}
#endregion
#region Public Properties
public int Id
{
get { return _Id; }
set { _Id = value; OnPropertyChanged("Id"); }
}
public string First_Name
{
get { return _First_Name; }
set { _First_Name = value;
OnPropertyChanged("First_Name"); }
}
public string Last_Name
{
get { return _Last_Name; }
set { _Last_Name = value; OnPropertyChanged("Last_Name"); }
}
public DateTime DOB
{
get { return _DOB; }
set { _DOB = value; OnPropertyChanged("DOB"); }
}
public clstbl_Contacts Contacts
{
get { return _Contacts; }
set
{
_Contacts = value;
OnPropertyChanged("Contacts");
GetValuesFromModel();
}
}
public ObservableCollection<clstbl_Contacts> ContactsList
{
get { return _ContactsList; }
set
{
_ContactsList = value;
OnPropertyChanged("ContactsList");
}
}
#endregion
#region Methods
private void LoadContacts()
{
clstbl_Contacts objContact = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
DataTable dt = objContact.Select();
_ContactsList = new ObservableCollection<clstbl_Contacts>();
for (int i = 0; i < dt.Rows.Count; i++)
{
_ContactsList.Add(new clstbl_Contacts { Id = Convert.ToInt16(dt.Rows[i]["ID"].ToString())
,First_Name = dt.Rows[i]["First_Name"].ToString(),
Last_Name = dt.Rows[i]["Last_Name"].ToString(),
DOB = Convert.ToDateTime(dt.Rows[i]["DOB"].ToString())
});
}
}
private void AddContacts()
{
clstbl_Contacts objContacts = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
objContacts.First_Name = First_Name;
objContacts.Last_Name = Last_Name;
objContacts.DOB = DOB;
objContacts.Insert();
}
private void GetValuesFromModel()
{
Id = _Contacts.Id;
First_Name = _Contacts.First_Name;
Last_Name = _Contacts.Last_Name;
DOB = _Contacts.DOB;
}
#endregion
#region Commands
public ICommand AddCommand
{
get
{
if (_addCommand == null)
{
_addCommand = new WPFnMVVM.Common.RelayCommand(
param => this.AddContacts(),
param => true
);
}
return _addCommand;
}
}
#endregion
}
}
View
<Window x:Class="WPFnMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:WPFnMVVM.ViewModel"
xmlns:View="clr-namespace:WPFnMVVM"
Title="MainWindow" Height="350" Width="337">
<Window.DataContext>
<VM:ContactsViewModel/>
</Window.DataContext>
<Grid Name="MyGrid">
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,13,0,0" TextWrapping="Wrap"
Text="{Binding Path=First_Name, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,47,0,0" TextWrapping="Wrap" Text="{Binding Path=Last_Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<Label Content="First Name" HorizontalAlignment="Left" Margin="8,10,0,0" VerticalAlignment="Top"/>
<Label Content="Last Name" HorizontalAlignment="Left" Margin="9,47,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<Label Content="DOB" HorizontalAlignment="Left" Margin="8,75,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<DatePicker Height="25" HorizontalAlignment="Left" Margin="95,76,0,0" Name="datePicker1"
VerticalAlignment="Top" Width="120" SelectedDate="{Binding Path=DOB, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="9,118,0,0" VerticalAlignment="Top" Width="75" Command="{Binding Path=AddCommand}"/>
<Button Content="Update" HorizontalAlignment="Left" Margin="102,118,0,0" VerticalAlignment="Top" Width="75"/>
<Button Content="Delete" HorizontalAlignment="Left" Margin="193,118,0,0" VerticalAlignment="Top" Width="75"/>
<ListView BorderBrush="White" ItemsSource="{Binding Path=ContactsList, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" Margin="11,156,10,10" SelectedValue="{Binding Path=Contacts, UpdateSourceTrigger=PropertyChanged}">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name"
DisplayMemberBinding="{Binding Path=First_Name}" Width="70" />
<GridViewColumn Header="Last Name"
DisplayMemberBinding="{Binding Path=Last_Name}" Width="70" />
<GridViewColumn Header="DOB"
DisplayMemberBinding="{Binding Path=DOB}" Width="70" />
</GridView>
</ListView.View>
</ListView >
</Grid>
</Window>