Your code has a few issues in the Xaml that caused problems. It is alway a good idea to keep it as clean as possible to make it readable. So here is a revised version for you:
<Window x:Class="WpfListViewEdit.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:WpfListViewEdit"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<local:UserViewModel/>
</Window.DataContext>
<Grid Margin="20">
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0 0 4 0"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Margin" Value="0 4"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="10 0"/>
<Setter Property="Padding" Value="10 5"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
<ColumnDefinition />
</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"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="_Id"
Target="{Binding ElementName=txtUserId}" />
<TextBox Name="txtUserId" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.UserId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="_First Name" Grid.Row="1"
Target="{Binding ElementName=txtFirstName}" />
<TextBox Name="txtFirstName" Grid.Row="1" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.FirstName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="_Last Name" Grid.Row="2"
Target="{Binding ElementName=txtLastName}" />
<TextBox Name="txtLastName" Grid.Row="2" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.LastName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="C_ity" Grid.Row="3"
Target="{Binding ElementName=txtCity}" />
<TextBox Name="txtCity" Grid.Row="3" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.City, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="S_tate" Grid.Row="4"
Target="{Binding ElementName=txtState}"/>
<TextBox Name="txtState" Grid.Row="4" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="C_ountry" Grid.Row="5"
Target="{Binding ElementName=txtCountry}" />
<TextBox Name="txtCountry" Grid.Row="5" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.Country ,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<StackPanel Orientation="Horizontal" Grid.Row="6" Grid.ColumnSpan="3" Margin="0 10" HorizontalAlignment="Center">
<Button Content="_Save" Command="{Binding SaveCommand}" />
<Button Content="_Update" Command="{Binding UpdateCommand}" />
<Button Content="_Delete" Command="{Binding DeleteCommand}" />
<Button Content="_Cancel" Command="{Binding CancelComand}"/>
</StackPanel>
<ListView Name="UserGrid" Grid.Row="7" ItemsSource="{Binding Users}" Grid.ColumnSpan="3" >
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
<GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
<GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
<GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
With these changes in place, the Window works as expected if (Mock) data is supplied. As you select rows in the listview, the TextBoxes reflect the selection; any changes made in the TextBoxes is reflected in the ListView; all in real time.
The layout seems to be upside-down. I would have expected the Listview to be at the top, buttons to Add, Edit, Delete to be with the ListView (side or bottom), and the edit pane (edit fields with Save & Cancel buttons) to appear (come into view) separated at the bottom or pop up in an edit window when one of the ListView buttons were used. Something like this:
<Window x:Class="WpfListViewEdit.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:WpfListViewEdit"
mc:Ignorable="d"
Title="MainWindow" Height="480" Width="600" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<local:UserViewModel/>
</Window.DataContext>
<Grid Margin="20">
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0 0 4 0"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Margin" Value="0 4"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="10 0 0 0"/>
<Setter Property="Padding" Value="10 5"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition MinHeight="140"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="UserGrid" ItemsSource="{Binding Users}" Grid.ColumnSpan="3" >
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
<GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
<GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
<GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0 10"
HorizontalAlignment="Right">
<Button Content="_Add" Command="{Binding AddCommand}" />
<Button Content="_Update" Command="{Binding UpdateCommand}" />
<Button Content="_Delete" Command="{Binding DeleteCommand}" />
</StackPanel>
</Grid>
<GroupBox Header="EDIT DETAILS" Grid.Row="1" Padding="10">
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="_Id"
Target="{Binding ElementName=txtUserId}" />
<TextBox Name="txtUserId" Grid.Column="1" IsReadOnly="True"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.UserId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="_First Name" Grid.Row="1"
Target="{Binding ElementName=txtFirstName}" />
<TextBox Name="txtFirstName" Grid.Row="1" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.FirstName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="_Last Name" Grid.Row="2"
Target="{Binding ElementName=txtLastName}" />
<TextBox Name="txtLastName" Grid.Row="2" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.LastName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="C_ity" Grid.Row="3"
Target="{Binding ElementName=txtCity}" />
<TextBox Name="txtCity" Grid.Row="3" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.City, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="S_tate" Grid.Row="4"
Target="{Binding ElementName=txtState}"/>
<TextBox Name="txtState" Grid.Row="4" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="C_ountry" Grid.Row="5"
Target="{Binding ElementName=txtCountry}" />
<TextBox Name="txtCountry" Grid.Row="5" Grid.Column="1"
Text="{Binding ElementName=UserGrid, Path=SelectedItem.Country ,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<StackPanel Orientation="Horizontal" Grid.Row="6" Grid.ColumnSpan="3" Margin="0 10" HorizontalAlignment="Right">
<Button Content="_Save" Command="{Binding SaveCommand}" />
<Button Content="_Cancel" Command="{Binding CancelComand}"/>
</StackPanel>
</Grid>
</GroupBox>
</Grid>
</Window>
Now the Window starts to make sense.
Lastly, the button won't work as you have not implemented your RelayCommand, well not in the code supplied.
UPDATE: Re-reading your question, I noticed that the above failed to answer the following:
Satya Praksh Mishra wrote:
unable to get textbox values in viewmodel
So, instead of binding the edit fields directly to the
Listview
, bind then and the
ListView.SelectedItem
to a property in the ViewModel.
In the following example, to keep code clean, I have bound the ViewModel's
SelectedUser
property to the
GroupBox
. Bindings Cascade from parent to child in XAML. So the Textboxes'
DataContext
is bound to the
SelectedUser
of the
UserViewModel
. Now we only need to bind to the properties of the
SelectedUser
property of type
User
.
Updated XAML:
<Window x:Class="WpfListViewEdit.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:WpfListViewEdit"
mc:Ignorable="d"
Title="Manage Users" Height="480" Width="600" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<local:UserViewModel/>
</Window.DataContext>
<Grid Margin="20">
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0 0 4 0"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Margin" Value="0 4"/>
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="10 0 0 0"/>
<Setter Property="Padding" Value="10 5"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition MinHeight="140"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="UserGrid" Grid.ColumnSpan="3"
ItemsSource="{Binding Users}"
SelectedItem="{Binding SelectedUser}">
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
<GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
<GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
<GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0 10"
HorizontalAlignment="Right">
<Button Content="_Add" Command="{Binding AddCommand}" />
<Button Content="_Update" Command="{Binding UpdateCommand}" />
<Button Content="_Delete" Command="{Binding DeleteCommand}" />
</StackPanel>
</Grid>
<GroupBox Header="EDIT DETAILS" Grid.Row="1" Padding="10" DataContext="{Binding SelectedUser}">
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="_Id"
Target="{Binding ElementName=txtUserId}" />
<TextBox Name="txtUserId" Grid.Column="1" IsReadOnly="True"
Text="{Binding UserId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="_First Name" Grid.Row="1"
Target="{Binding ElementName=txtFirstName}" />
<TextBox Name="txtFirstName" Grid.Row="1" Grid.Column="1"
Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="_Last Name" Grid.Row="2"
Target="{Binding ElementName=txtLastName}" />
<TextBox Name="txtLastName" Grid.Row="2" Grid.Column="1"
Text="{Binding LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="C_ity" Grid.Row="3"
Target="{Binding ElementName=txtCity}" />
<TextBox Name="txtCity" Grid.Row="3" Grid.Column="1"
Text="{Binding City, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="S_tate" Grid.Row="4"
Target="{Binding ElementName=txtState}"/>
<TextBox Name="txtState" Grid.Row="4" Grid.Column="1"
Text="{Binding State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="C_ountry" Grid.Row="5"
Target="{Binding ElementName=txtCountry}" />
<TextBox Name="txtCountry" Grid.Row="5" Grid.Column="1"
Text="{Binding Country ,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<StackPanel Orientation="Horizontal" Grid.Row="6" Grid.ColumnSpan="3" Margin="0 10" HorizontalAlignment="Right">
<Button Content="_Save" Command="{Binding SaveCommand}" />
<Button Content="_Cancel" Command="{Binding CancelComand}"/>
</StackPanel>
</Grid>
</GroupBox>
</Grid>
</Window>
Updated
UserViewModel
:
internal class UserViewModel : INotifyPropertyChanged
{
private User selectedUser;
private ObservableCollection<User> _UsersList;
public UserViewModel()
{
GetUserList();
}
private void GetUserList()
{
Users = new ObservableCollection<User>();
for (int i = 0; i < 100; i++)
{
Users.Add(new User
{
UserId = 1000 + i,
FirstName = $"FirstName {i}",
LastName = $"LastName {i}",
City = $"City {i}",
State = $"State {i}",
Country = $"Country {i}"
});
}
}
public ObservableCollection<User> Users { get; set; }
public User SelectedUser
{
get { return selectedUser; }
set
{
if (selectedUser != value)
{
selectedUser = value;
NotifyPropertyChanged(nameof(SelectedUser));
}
}
}
#region SaveCommand
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
Now the
ListView.SelectedItem
is visible to the
UserViewModel
.