Hi I am using WPF and MVVM, There is "Edit/Update" Panel in my application it updates selected data in Grid. It is working fine. I want to add one button "Close Button" and "one check to see whether user has selected item or not. If he doesn't select any item and click on "Edit Button" It will show a MessageBox to user to select an item to edit. Thing i am not getting clear is that how to pass "Selected item to do these two things" and to check before closing panel that is there any text in textbox fields or not.
User View Model Code:
public class UserViewModel
{
private IList<User> _UsersList;
public UserViewModel()
{
_UsersList = new List<User>
{
new User { UserId = 1, FirstName = "Raj", LastName = "Beniwal", City = "Delhi", State = "DEL", Country = "INDIA" },
new User { UserId = 2, FirstName = "Mark", LastName = "henry", City = "New York", State = "NY", Country = "USA" },
new User { UserId = 3, FirstName = "Mahesh", LastName = "Chand", City = "Philadelphia", State = "PHL", Country = "USA" },
new User { UserId = 4, FirstName = "Vikash", LastName = "Nanda", City = "Noida", State = "UP", Country = "INDIA" },
new User { UserId = 5, FirstName = "Harsh", LastName = "Kumar", City = "Ghaziabad", State = "UP", Country = "INDIA" },
new User { UserId = 6, FirstName = "Reetesh", LastName = "Tomar", City = "Mumbai", State = "MP", Country = "INDIA" },
new User { UserId = 7, FirstName = "Deven", LastName = "Verma", City = "Palwal", State = "HP", Country = "INDIA" },
new User { UserId = 8, FirstName = "Ravi", LastName = "Taneja", City = "Delhi", State = "DEL", Country = "INDIA" }
};
}
public IList<User> Users
{
get { return _UsersList; }
set { _UsersList = value; }
}
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
{
mUpdater = new Updater();
}
return mUpdater;
}
set
{
mUpdater = 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
}
}
User View Window.Xaml
Panel1
<dxdo:LayoutPanel Caption="Panel1" x:Name="Panel1">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Name="UserGrid" Grid.Row="1" Margin="4,178,12,13" ItemsSource="{Binding Users}">
<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>
</dxdo:LayoutPanel>
<dxdo:LayoutPanel x:Name="Panel3">
<Grid>
<StackPanel>
<Button Content="Edit" Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" Width="141" Click="Button_Click_1" />
</StackPanel>
</Grid>
</dxdo:LayoutPanel>
Panel2:
<dxdo:LayoutPanel Caption="Panel2" x:Name="Panel2">
<Grid>
<StackPanel Margin="0,0,0,10">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid, Path=SelectedItem.UserId}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid, Path=SelectedItem.FirstName}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,62,0,0" Name="txtLastName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid, Path=SelectedItem.LastName}" />
<Label Content="UserId" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
<Label Content="Last Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,60,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="First Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,143,0,0" x:Name="txtCity" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.City, ElementName=UserGrid}" />
<Label Content="Country" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,141,0,0" x:Name="label2_Copy" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,88,0,0" x:Name="txtCountry" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.Country, ElementName=UserGrid}" />
<Label Content="City" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,86,0,0" x:Name="label2_Copy1" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,115,0,0" x:Name="txtSTate" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.State, ElementName=UserGrid}" />
<Label Content="State" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,113,0,0" x:Name="label2_Copy2" VerticalAlignment="Top" />
</Grid>
<Button Content="Update" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="310,40,0,0" Name="btnUpdate" VerticalAlignment="Top" Width="141" Command="{Binding Path=UpdateCommad}" />
<Button Content="Close" Grid.Row="1" Height="23" HorizontalAlignment="Right" VerticalAlignment="Top" Width="141" Click="Button_Click_2" />
<TextBox Width="166" Background="White" Height="33" HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="{Binding Path=SelectedCustomer.LastName,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Grid>
</dxdo:LayoutPanel>
(If my question is not clear to you plesae ask me. Thank you)
Create a Property in the ViewModel for saving the selected User:
public User SelectedUser { get; set; }
Bind SelectedItem of the ListView to this Property:
<ListView Name="UserGrid" ItemsSource="{Binding Users}" SelectedItem="{Binding SelectedUser}">
Now you just have to check if the SelectedUser property is null.
how to pass "Selected item to do these two things"
This usually can be achieved with SelectedSomething property in your view model. This property should be bound to SelectedItem of control.
and to check before closing panel that is there any text in textbox fields or not
This is called "validation". WPF supports validation in several ways, one of them is implementing IDataErrorInfo in your view model. I'd recommend this way, because it is a de facto standard for .NET (it is used in WinForms and ASP .NET as well).
one check to see whether user has selected item or not. If he doesn't select any item and click on "Edit Button" It will show a MessageBox to user to select an item to edit
Again, usually, this being solved with ICommand instance, bound to the button. If ICommand.CanExecute returns false, bound button becomes disabled.
For example, you should check for validation errors in CanExecute for command, bound to Close button, and return false, if there are any errors. Or you should check SelectedSomething property in CanExecute for command, bound to Edit button, and return false, if SelectedSomething == null.
In MVVM world thing becomes easier, if you use RelayCommand/DelegateCommand as the default ICommand implementation.
Update.
A code sample for commands.
View model:
public class UserViewModel
{
public UserViewModel()
{
EditCommand = new RelayCommand(EditSelectedUser, () => SelectedUser != null);
}
private void EditSelectedUser()
{
// some edit code here
}
public User SelectedUser { get; set; }
public ICommand EditCommand { get; private set; }
}
XAML:
<Button Content="Edit" Command="{Binding EditCommand}"/>
Related
I have a datagrid which holds the User information. Now once, I click on the selected row, I want to display the user information such as their roles and allow the user to edit the user roles by clicking on the combobox. Under my data template I have the combobox in my xaml. Since using the datatemplate, the combobox name couldnt be found, I am using the following method below to get the children from the grid.
Here is the code to get the children element:
private List<FrameworkElement> GetChildren(DependencyObject parent)
{
List<FrameworkElement> controls = new List<FrameworkElement>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); ++i)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is FrameworkElement)
{
controls.Add(child as FrameworkElement);
}
controls.AddRange(GetChildren(child));
}
return controls;
}
I created the selection changed event for the datagrid:
private void userDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var userRolesList = new User().getUserRoles();
ComboBox cbUserRole = (ComboBox)GetChildren(userDataGrid).First(x => x.Name == "cbUserRole");
cbUserRole.ItemsSource = userRolesList;
}
Now when I run this code, I am being shown error message
Sequence contains no matching element
The same method I use for my textboxes, I am able to display the values and edit the values too. But for my combobox its not working the way it supposed to. Can someone please help me on this. Thanks.
This is my xaml code:
<DataGrid AutoGenerateColumns="False" Grid.Row="2" Grid.ColumnSpan="4" Grid.RowSpan="3" x:Name="userDataGrid" Margin="70,0.2,70,0" ItemsSource="{Binding}" SelectionChanged="userDataGrid_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding UserId}"/>
<DataGridTextColumn Header="Username" Binding="{Binding UserName}"/>
<DataGridTextColumn Header="Email" Binding="{Binding UserEmail}"/>
<DataGridTextColumn Header="User Role" Binding="{Binding UserRole}"/>
<DataGridTextColumn Header="Created Date" Binding="{Binding UserCreatedDate}"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User ID: " VerticalAlignment="Center" />
<TextBlock x:Name="txtBlockId" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserId, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="First Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtFirstName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserFirstName, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Last Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtLastName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserLastName}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User Role: " VerticalAlignment="Center" />
<ComboBox x:Name="cbUserRole" FlowDirection="LeftToRight" FontSize="16" Foreground="MidnightBlue" HorizontalAlignment="Stretch" VerticalAlignment="Center" SelectionChanged="cbUserRole_Click"/>
</StackPanel>
<StackPanel>
<Button x:Name="btnUpdate" Content="Update" VerticalAlignment="Center" HorizontalAlignment="Right" Click="btnUpdate_Click"/>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Thanks
I've been seeing you asking around how to work with this, let me show you one way, hope this helps, but I recommend you read about MVVM patterns and frameworks like MVVMLight for WPF.
Well, for this, first you need to install Install-Package MvvmLight -Version 5.4.1
Then you may need to fix one reference issue, in the ViewModelLocator, remove all the usings and replace with:
using GalaSoft.MvvmLight.Ioc;
using CommonServiceLocator;
Now, your MainWindowView.xaml, it should like:
<Window x:Class="WpfApp2.MainWindow"
x:Name="root"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:WpfApp2.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<vm:MainViewModel x:Name="Model"/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid AutoGenerateColumns="False" x:Name="userDataGrid" Margin="70,0.2,70,0" ItemsSource="{Binding Users}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding UserId}"/>
<DataGridTextColumn Header="Username" Binding="{Binding UserName}"/>
<DataGridTextColumn Header="Email" Binding="{Binding UserEmail}"/>
<DataGridTextColumn Header="User Role" Binding="{Binding UserRole}"/>
<DataGridTextColumn Header="Created Date" Binding="{Binding UserCreatedDate}"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User ID: " VerticalAlignment="Center" />
<TextBlock x:Name="txtBlockId" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserId, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="First Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtFirstName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserFirstName, Mode=TwoWay}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Last Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtLastName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserLastName}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User Role: " VerticalAlignment="Center" />
<ComboBox ItemsSource="{Binding Path=DataContext.UserRoles, ElementName=root}" SelectionChanged='CbUserRole_OnSelectionChanged' SelectedItem="{Binding UserRole}" x:Name="cbUserRole" FlowDirection="LeftToRight" FontSize="16" Foreground="MidnightBlue" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
</StackPanel>
<StackPanel>
<Button x:Name="btnUpdate" Content="Update" VerticalAlignment="Center" HorizontalAlignment="Right" Command="{Binding UpdateCommand, ElementName=Model}" CommandParameter="{Binding}" />
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
</Window>
Then in your code-behind, there's a little event handling that needs to be done, when changing the roles,
using System.Windows;
using System.Windows.Controls;
using WpfApp2.ViewModel;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public MainViewModel ViewModel => (MainViewModel) DataContext;
private void CbUserRole_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox cb = (ComboBox)sender;
if (cb != null)
{
ViewModel.SelectedUserRole = (UserRole)cb.SelectedItem;
}
}
}
}
Then you should create a ViewModel like so (ViewModel -> MainViewModel.cs):
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using GalaSoft.MvvmLight.Command;
using WpfApp2.Data;
namespace WpfApp2.ViewModel
{
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
PopulateUserTestData();
UpdateCommand = new RelayCommand<User>(UpdateUser);
}
private ObservableCollection<User> _users;
public ObservableCollection<User> Users
{
get => _users;
set
{
if (_users != value)
{
_users = value;
NotifyPropertyChanged();
}
}
}
private UserRole _userRole;
public UserRole SelectedUserRole
{
get => _userRole;
set
{
if (_userRole != value)
{
_userRole = value;
NotifyPropertyChanged();
}
}
}
public RelayCommand<User> UpdateCommand { get; }
public IEnumerable<UserRole> UserRoles => Enum.GetValues(typeof(UserRole)).Cast<UserRole>();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void UpdateUser(User user)
{
Users.Single(u => u.UserId == user.UserId).UserRole = SelectedUserRole;
// Do updates on your context (or in-memory).
PrintUsersOnDebug();
}
#region Test data and diagnostics support
private void PrintUsersOnDebug()
{
foreach (User user in Users)
{
Debug.WriteLine("Username: " + user.UserName + " Role: " + user.UserRole);
}
}
private void PopulateUserTestData()
{
Users = new ObservableCollection<User>
{
new User
{
UserId = 1,
UserCreatedDate = DateTime.Now,
UserEmail = "johndoe1#email.com",
UserFirstName = "John",
UserLastName = "Doe",
UserName = "johnd",
UserRole = UserRole.Administrator
},
new User
{
UserId = 2,
UserCreatedDate = DateTime.Now,
UserEmail = "billgordon#email.com",
UserFirstName = "Bill",
UserLastName = "Gordon",
UserName = "billg",
UserRole = UserRole.SuperUser
}
};
PrintUsersOnDebug();
}
#endregion
}
}
Other related classes:
Data->User.cs
using System;
namespace WpfApp2.Data
{
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public string UserEmail { get; set; }
public UserRole UserRole { get; set; }
public DateTime UserCreatedDate { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
}
}
UserRole.cs
namespace WpfApp2
{
public enum UserRole
{
Administrator,
User,
SuperUser
}
}
Now since I just designed this test app to view the changing data in this case roles, I designed this to be just viewable on output window. As you change the roles and click the update button, inspect the output window.
If you simply want to populate the ComboBox in the RowDetailsTemplate, you could handle its Loaded event:
private void cbUserRole_Loaded(object sender, RoutedEventArgs e)
{
ComboBox cbUserRole = (ComboBox)sender;
if (cbUserRole.ItemsSource == null)
cbUserRole.ItemsSource = new User().getUserRoles();
}
XAML:
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="User Role: " VerticalAlignment="Center" />
<ComboBox x:Name="cbUserRole"
Loaded="cbUserRole_Loaded"
FlowDirection="LeftToRight" FontSize="16" Foreground="MidnightBlue" HorizontalAlignment="Stretch"
VerticalAlignment="Center"
SelectionChanged="cbUserRole_Click"/>
</StackPanel>
I have created a combo box and im binding in MVVM pattern, but my properties are not binding to the view, I'm confused with itemsource and selectvalue.
What changes can I make to view.xaml? I'm guessing the remainder of the code in my model and view model are perfect.
This is my Model
namespace screensaver.Models {
class ConfigurationModel {
public int _resolution;
private ObservableCollection < ConfigurationModel > Resolution {
get {
return Resolution;
}
set {
Resolution = value;
}
}
public ConfigurationModel() {
Resolution = new ObservableCollection < ConfigurationModel > () {
new ConfigurationModel() {
_resolution = 360 * 720
},
new ConfigurationModel() {
_resolution = 720 * 1080
},
new ConfigurationModel() {
_resolution = 1080 * 2060
}
};
}
}
}
This is my ViewModel
namespace screensaver.ViewModels {
class ConfigurationViewModel {
private ObservableCollection < ConfigurationModel > _resolution;
public ObservableCollection < ConfigurationModel > Resolution {
get {
return Resolution;
}
set {
Resolution = value;
}
}
}
}
This is my View xaml code
<Window x:Class="screensaver.Views.ConfigurationWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:screensaver.ViewModels" Title="ConfigurationWindow"
Height="1000" Width="500">
<Grid>
<Label Content="Display" HorizontalAlignment="Left" Margin="7,12,0,0" VerticalAlignment="Top" />
<ComboBox HorizontalAlignment="Left" Margin="322,14,0,0" VerticalAlignment="Top" Width="120" />
<ComboBox ItemsSource="{Binding Resolution}" SelectedItem="{Binding
Resolution, Mode=TwoWay}" DisplayMemberPath="{Binding Resolution}" HorizontalAlignment="Left" Margin="74,13,0,0" VerticalAlignment="Top" Width="120" />
<Label Content="Resolution" HorizontalAlignment="Left" Margin="250,13,0,0" VerticalAlignment="Top" />
<Button Content="Save" HorizontalAlignment="Left" Margin="80,362,0,0" VerticalAlignment="Top" Width="75" />
<Button Content="Close" HorizontalAlignment="Left" Margin="350,360,0,0" VerticalAlignment="Top" Width="75" />
<Label Content="Height" HorizontalAlignment="Left" Margin="72,178,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="140,181,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<Label Content="Width" HorizontalAlignment="Left" Margin="290,175,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="346,179,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<Label Content="Top" HorizontalAlignment="Left" Margin="76,253,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="140,255,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<Label Content="Left" HorizontalAlignment="Left" Margin="292,250,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="349,252,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>
There are some problems with your code.
First fix your property Resolution in ViewModel to prevent a StackOverflowException. Use your field _resolution in get and set.
private ObservableCollection < ConfigurationModel > Resolution {
get {
return _resolution;
}
set {
_resolution = value;
}
}
Similar problem in your Model. Here you can use an auto-property
private ObservableCollection<ConfigurationModel> Resolution
{
get;
set;
}
Maybe you should also exchange the ObservableCollection by a List<>. But this is not necessary. The field _resolution can be removed and the type of Resolution poperty changed to ObservableCollection< string >.
private ObservableCollection<string> Resolution
{
get;
set;
}
Your constructor can then be changed to
public ConfigurationModel()
{
Resolution = new ObservableCollection<string>() {
"360 * 720",
"720 * 1080",
"1080 * 2060"
};
}
There is also missing the link from Model to ViewModel. Something like that:
private readonly ConfigurationModel _model;
public ConfigurationViewModel()
{
_model = new ConfigurationModel();
}
And then you have to use it, so you have to change your property
public ObservableCollection<string> Resolution
{
get
{
return _model.Resolution;
}
set
{
_model.Resolution = value;
}
}
Therefore you have to change the modifier in the Model from private to public.
public ObservableCollection<string> Resolution
{
get;
set;
}
Now you can remove the field _resolution from ViewModel.
DisplayMemberPath have to be removed from the View. And you have to set the DataContext properly.
<Window.DataContext>
<ViewModels:ConfigurationViewModel />
</Window.DataContext>
So far you have that result:
The SelectedItem in the View have to bind to another property in the ViewModel.
public string SelectedResolution { get; set; }
SelectedItem="{Binding SelectedResolution, Mode=TwoWay}"
This should be a good starting point to go further on. You can change the string in the ObservableCollection to an own type with more properties. Then you need to set the DisplayMemberPath again.
Here is the final code.
Model:
using System.Collections.ObjectModel;
namespace screensaver.Models
{
class ConfigurationModel
{
public ObservableCollection<string> Resolution
{
get;
set;
}
public ConfigurationModel()
{
Resolution = new ObservableCollection<string>() {
"360 * 720",
"720 * 1080",
"1080 * 2060"
};
}
}
}
ViewModel:
using screensaver.Models;
using System.Collections.ObjectModel;
namespace screensaver.ViewModels
{
class ConfigurationViewModel
{
private readonly ConfigurationModel _model;
public ConfigurationViewModel()
{
_model = new ConfigurationModel();
}
public ObservableCollection<string> Resolution
{
get { return _model.Resolution; }
set { _model.Resolution = value; }
}
public string SelectedResolution { get; set; }
}
}
View:
<Window x:Class="screensaver.Views.ConfigurationWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:screensaver.ViewModels" Title="ConfigurationWindow"
Height="1000" Width="500">
<Window.DataContext>
<ViewModels:ConfigurationViewModel />
</Window.DataContext>
<Grid>
<Label Content="Display" HorizontalAlignment="Left" Margin="7,12,0,0" VerticalAlignment="Top" />
<ComboBox HorizontalAlignment="Left" Margin="322,14,0,0" VerticalAlignment="Top" Width="120" />
<ComboBox ItemsSource="{Binding Resolution}" SelectedItem="{Binding SelectedResolution, Mode=TwoWay}" HorizontalAlignment="Left" Margin="74,13,0,0" VerticalAlignment="Top" Width="120" />
<Label Content="Resolution" HorizontalAlignment="Left" Margin="250,13,0,0" VerticalAlignment="Top" />
<Button Content="Save" HorizontalAlignment="Left" Margin="80,362,0,0" VerticalAlignment="Top" Width="75" />
<Button Content="Close" HorizontalAlignment="Left" Margin="350,360,0,0" VerticalAlignment="Top" Width="75" />
<Label Content="Height" HorizontalAlignment="Left" Margin="72,178,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="140,181,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<Label Content="Width" HorizontalAlignment="Left" Margin="290,175,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="346,179,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<Label Content="Top" HorizontalAlignment="Left" Margin="76,253,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="140,255,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<Label Content="Left" HorizontalAlignment="Left" Margin="292,250,0,0" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="349,252,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>
I have one action in my view model to add record in to entity frame work.I have one action to display the records in the view like this :
private void FillProspects()
{
var q = (from a in ctx2.Prospects// 'ctx' is the object of entity
select a).ToList();
this.Prospects = q; // 'Porspects' is a collection of entity class this I have bound with my List view in my view
}
This will be called in construction of my view model.as a result the list view in my view will be showing the records .
I have one add record action in my view model..I have created properties in my view model corresponding to properties generated in the entity class for example:
private String _FirstName;
public String FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
And my add record action in the view model is :
public void Add1()
{
newprospect = new Prospect();
newprospect.ID = Guid.NewGuid();
newprospect.FirstName = FirstName;
newprospect.LastName = LastName;
newprospect.Address = Address;
newprospect.State = State;
newprospect.City = City;
newprospect.ZIP = ZIP;
prospect = newprospect;
ctx2.AddToProspects(prospect);
FillProspects();
//RaisePropertyChanged("Prospects");
}
I have inherited the : INotifyPropertyChanged and imported it's
using System.Windows.Input;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void RaisePropertyChanged(string property) { PropertyChanged(this, new PropertyChangedEventArgs(property)); }
But my notification is not refreshing my view Listview records after adding record .so I just call the fill records method 'FillProspects' in the addrecord action..Is this right way of doing MVVM .Why my Listview is not getting refreshed after add record action where I am missing?I have tried with
RaisePropertyChanged("Prospects");in the Add record action...but it is not refreshing .So I just called fill method action again
My complete view model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Input;
using System.Collections.ObjectModel;
namespace Wpfentity3
{
public class frmProspects_VM : INotifyPropertyChanged
{
TestsEntities ctx2 = new TestsEntities();
public ObservableCollection<Prospect> prospects { get; set; }
//This is the collection where records - er, entities - returned by a query are stored;
//Prospect is the generated class that defines a record - er,
//an entity as well as the query for that table.
private CommandMap _Commands;
public CommandMap Commands { get { return _Commands; } }
Prospect newprospect;
//This holds a new prospect that is created and then added to the prospects collection
private Prospect _prospect;
public Prospect prospect {
get
{
return _prospect;
}
set
{
_prospect = value;
RaisePropertyChanged("prospect");
}
}
//prospect is the object that holds the current record from the Prospects table.
//MainWindow controls are bound to this object
public frmProspects_VM()
{
//FillProspects();
ctx2 = new TestsEntities();
//This instantiates the EntityManager class ;
prospects = new ObservableCollection<Prospect>();
//This instantiates the prospects collection of Prospect records - er, entities;
_Commands = new CommandMap();
_Commands.AddCommand("Add", x => Add1());
}
private ObservableCollection<Prospect> _prospects;
public ObservableCollection<Prospect> Prospects
{
get
{
return _prospects;
}
set
{
_prospects = value;
RaisePropertyChanged("Prospects");
}
}
private String _FirstName;
public String FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
private String _LastName;
public String LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
}
}
private String _Address;
public String Address
{
get
{
return _Address;
}
set
{
_Address = value;
}
}
private String _State;
public String State
{
get
{
return _State;
}
set
{
_State = value;
}
}
private String _City;
public String City
{
get
{
return _City;
}
set
{
_City = value;
}
}
private String _ZIP;
public String ZIP
{
get
{
return _ZIP;
}
set
{
_ZIP = value;
}
}
public void Add1()
{
newprospect = new Prospect();
newprospect.ID = Guid.NewGuid();
newprospect.FirstName = FirstName;
newprospect.LastName = LastName;
newprospect.Address = Address;
newprospect.State = State;
newprospect.City = City;
newprospect.ZIP = ZIP;
prospect = newprospect;
ctx2.AddToProspects(prospect);
Prospects.Add(newprospect);
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void RaisePropertyChanged(string property) { PropertyChanged(this, new PropertyChangedEventArgs(property)); }
}
}
My view xamal:
<Window x:Class="Wpfentity3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="CenterScreen"
Title="Prospects"
Height="482" Width="500" MaxWidth="500" MaxHeight="600"
xmlns:cusns="clr-namespace:Wpfentity3">
<StackPanel Height="290" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" >
<Label
Content="Prospects"
BorderBrush="Blue" BorderThickness="1"
HorizontalAlignment="Left" VerticalAlignment="Top"
FontSize="24" FontFamily="Comic Sans MS"
Padding="13,3,13,9" Margin="5"
Foreground="Purple" Background="LemonChiffon" />
<Label
Content="{Binding Path=label}" Foreground="Red" FontSize="14"
HorizontalAlignment="Right" VerticalAlignment="Center"
Height="auto" Margin="180,0,10,0" />
</StackPanel>
<Grid
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="120" Width="475" >
<Grid.RowDefinitions>
<RowDefinition Height="25*" />
<RowDefinition Height="25*" />
<RowDefinition Height="25*" />
<RowDefinition Height="25*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="135*" />
<ColumnDefinition Width="45*" />
<ColumnDefinition Width="32*" />
<ColumnDefinition Width="57*" />
<ColumnDefinition Width="118*" />
</Grid.ColumnDefinitions>
<Label
Content="First name"
Grid.Row="0" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtFirstName"
Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=FirstName}"
Width="130" />
<Label
Content="Last name"
Grid.Row="1" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtLastName"
Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding LastName}"
Width="130" />
<Label
Content="Address"
Grid.Row="2" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtAddress"
Grid.Row="2" Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Address}"
Width="300" Grid.ColumnSpan="5" />
<Label
Content="City"
Grid.Row="3" Grid.Column="0" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtCity"
Grid.Row="3" Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding City}"
Width="130" />
<Label
Content="State"
Grid.Row="3" Grid.Column="2" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtState"
Grid.Row="3" Grid.Column="3" Width="30" MaxLength="2" CharacterCasing="Upper" Text="{Binding State}"
HorizontalAlignment="Left" VerticalAlignment="Center" />
<Label
Content="ZIP code"
Grid.Row="3" Grid.Column="4" Margin="0,0,5,0"
HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Name="txtZIP"
Grid.Row="3" Grid.Column="5" MaxLength="10"
HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding ZIP}"
Width="90" />
</Grid>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Button Name="btnFind"
Content="_Find"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnAdd"
Content="_Add" Command="{Binding Commands.Add}"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnEdit"
Content="_Edit"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnDelete"
Content="_Delete"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnSave"
Content="_Save"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnCancel"
Content="_Cancel"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
<Button Name="btnClose"
Content="Cl_ose"
Width="auto" Margin="5,0,5,0" Padding="10,0,10,0"
/>
</StackPanel>
<StackPanel Height="34" Margin="10">
<Grid Margin="10">
<ListView Name="lvprospects" ItemsSource="{Binding Prospects}" Margin="0,0,0,-200">
<ListView.View>
<GridView>
<GridViewColumn Header="FirstName" Width="120" DisplayMemberBinding="{Binding FirstName}" />
<GridViewColumn Header="LastName" Width="50" DisplayMemberBinding="{Binding LastName}" />
<GridViewColumn Header="Address" Width="50" DisplayMemberBinding="{Binding Address}" />
<GridViewColumn Header="City" Width="50" DisplayMemberBinding="{Binding City}" />
<GridViewColumn Header="State" Width="50" DisplayMemberBinding="{Binding State}" />
<GridViewColumn Header="ZIP" Width="50" DisplayMemberBinding="{Binding ZIP}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</StackPanel>
</StackPanel>
Change the type of the Prospects property from List<Prospect> to ObservableCollection<Prospect>:
private ObservableCollection<Prospect> _prospects = new ObservableCollection<Prospect>();
public ObservableCollection<Prospect> Prospects
{
get
{
return _prospects;
}
set
{
_prospects = value;
RaisePropertyChanged("Prospects");
}
}
And add the new Prospect object to this collection as well in your Add1 method:
public void Add1()
{
newprospect = new Prospect();
newprospect.ID = Guid.NewGuid();
newprospect.FirstName = FirstName;
newprospect.LastName = LastName;
newprospect.Address = Address;
newprospect.State = State;
newprospect.City = City;
newprospect.ZIP = ZIP;
prospect = newprospect;
ctx2.AddToProspects(prospect);
Prospects.Add(newprospect);
}
Just adding it to the DbContext doesn't affect the ListView.
It is fine to add the new item to the DB and then retrieve again the collection with the same refresh method FillProspects:
what you're doing is basically correct.
If you're going to bind a view to a collection in your ViewModel, I suggest using an ObservableCollection.
The ObservableCollection implements INotifyCollectionChanged, it notifies the view when elements are added or removed.
With this you should not need your "FillProspects" method and your "RaisePropertyChanged("Prospects")".
If you want more information I suggest posting how you bind in your XAML and also how you construct your "Prospects" object (we don't even know what type it is, I just assume it isn't an ObservableCollection).
EDIT :
you bind your ListView to "Prospects", but in your ViewModel, I see that "Prospects" is of type "List", it needs to be "ObservableCollection". I see that you have an ObservableCollection named "prospects", but you don't use it anywhere. Could this be the issue ?
I have a table named Groups in my Database as follows:
Groups
|--GroupID
|--GroupName
|--ParentID
|--NatureOfGroupID
|--EffectID
Here is the relationship diagram for above table:
I have a combobox in a window in which I have two columns. Here is the xaml:
<ComboBox ItemsSource="{Binding DataContext.GroupNamesWithCorrespondingEffects, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"
SelectedValue="{Binding ParentID}" SelectedValuePath="GroupID">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupName}" Width="200" />
<TextBlock Text="{Binding CorrespondingEffect}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Actually i want to show GroupName and its corresponding Effect but when user selects any Item then I want to get SelectedValue as ParentID.
Here is the implementation of GroupNameWithCorrespondingEffect.cs
public class GroupNameWithCorrespondingEffect : MainViewModel
{
private string _groupName;
public string GroupName
{
get
{
return _groupName;
}
set
{
_groupName = value;
OnPropertyChanged("GroupName");
}
}
private string _correspondingEffect;
public string CorrespondingEffect
{
get
{
return _correspondingEffect;
}
set
{
_correspondingEffect = value;
OnPropertyChanged("CorrespondingEffect");
}
}
}
Here is the code for groupsViewModel.cs
public class GroupsViewModel : MainViewModel
{
public GroupsViewModel()
{
using (Entities db = new Entities())
{
GroupNamesWithCorrespondingEffects = (from g in db.Groups
select new GroupNameWithCorrespondingEffect
{
GroupName = g.GroupName,
CorrespondingEffect = g.Master_Effects.Effect
}).ToList();
NaturesOfGroup = (from m in db.Master_NatureOfGroup
select m).ToList();
}
SaveChangesCommand = new RelayCommand(SaveGroup);
CurrentGroup = new Group();
}
private Group _currentGroup;
public Group CurrentGroup
{
get
{
return _currentGroup;
}
set
{
_currentGroup = value;
OnPropertyChanged("CurrentGroup");
}
}
private List<GroupNameWithCorrespondingEffect> _groupNamesWithCorrespondingEffects;
public List<GroupNameWithCorrespondingEffect> GroupNamesWithCorrespondingEffects
{
get
{
return _groupNamesWithCorrespondingEffects;
}
set
{
_groupNamesWithCorrespondingEffects = value;
OnPropertyChanged("GroupNamesWithCorrespondingEffects");
}
}
private List<Master_NatureOfGroup> _naturesOfGroup;
public List<Master_NatureOfGroup> NaturesOfGroup
{
get
{
return _naturesOfGroup;
}
set
{
_naturesOfGroup = value;
OnPropertyChanged("NaturesOfGroup");
}
}
public ICommand SaveChangesCommand { get; set; }
private void SaveGroup(object obj)
{
Group cGroup = new Group()
{
GroupName = CurrentGroup.GroupName,
**ParentID = CurrentGroup.ParentID,**
NatureOfGroupID = CurrentGroup.NatureOfGroupID,
EffectID = CurrentGroup.EffectID
};
using (Entities db = new Entities())
{
db.Groups.Add(cGroup);
db.SaveChanges();
GroupNamesWithCorrespondingEffects = (from g in db.Groups
select new GroupNameWithCorrespondingEffect
{
GroupName = g.GroupName,
CorrespondingEffect = g.Master_Effects.Effect
}).ToList();
}
}
}
When I debug and put a breakpoint on the line marked with ** .... ** I always get CurrentGroup.ParentID = null.
Update:
<Page.DataContext>
<vm:GroupsViewModel />
</Page.DataContext>
<Grid DataContext="{Binding CurrentGroup}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="0.6*" />
<ColumnDefinition Width="0.6*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Grid.Column="1" Text="Name" HorizontalAlignment="Left"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text=" : " HorizontalAlignment="Right"/>
<TextBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Text="{Binding GroupName}"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="Under" HorizontalAlignment="Left"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text=" : " HorizontalAlignment="Right"/>
<ComboBox x:Name="cbUnder" Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2"
ItemsSource="{Binding DataContext.GroupNamesWithCorrespondingEffects, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"
SelectedValue="{Binding ParentID}" SelectedValuePath="GroupID">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupName}" Width="200" />
<TextBlock Text="{Binding CorrespondingEffect}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="3" Grid.Column="1" Text="Nature of Group" HorizontalAlignment="Left" Visibility="{Binding Visibility, ElementName=cbNature}"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text=" : " HorizontalAlignment="Right" Visibility="{Binding Visibility, ElementName=cbNature}"/>
<ComboBox x:Name="cbNature" Grid.Row="3" Grid.Column="2" Visibility="{Binding SelectedIndex, Converter={StaticResource selectedIndexToVisibilityConverter}, ElementName=cbUnder}"
ItemsSource="{Binding DataContext.NaturesOfGroup, RelativeSource={RelativeSource AncestorType={x:Type Page}}}" DisplayMemberPath="Nature"
SelectedValue="{Binding NatureOfGroupID}" SelectedValuePath="NatureOfGroupID"/>
<StackPanel Grid.Row="5" Grid.Column="4" Orientation="Horizontal">
<Button Content="Save" Command="{Binding DataContext.SaveChangesCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"/>
</StackPanel>
</Grid>
I can see two issues in your code.
First of all you mentioned
Actually i want to show GroupName and its corresponding Effect but
when user selects any Item then I want to get SelectedValue as
ParentID.
But in combobox declaration, you set SelectedValuePath="GroupID". It should be set to ParentID - SelectedValuePath="ParentID".
Second, even if you set SelectedValuePath to ParentID, it won't work since combobox ItemsSource is a list of GroupNameWithCorrespondingEffect which doesn't have any property ParentID in it.
For SelectedValuePath to work underlying model class should have that property, so create a property and filled it from database like other two properties.
GroupNamesWithCorrespondingEffects = (from g in db.Groups
select new GroupNameWithCorrespondingEffect
{
GroupName = g.GroupName,
CorrespondingEffect = g.Master_Effects.Effect,
ParentID = g.ParentId
}).ToList();
So, for your solution to work, you have to fix both these issues.
I have made a wpf application for implementing the MVVM architecture. I can see the forma but the data is not loaded in the form please help is needed. I am using Visual studio 2012.
Below is the code:
Model:- User.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace TestApplication.Model
{
public class User : INotifyPropertyChanged
{
private int userId;
private string firstName;
private string lastName;
private string city;
private string state;
private string country;
public int UserId
{
get
{
return userId;
}
set
{
userId = value;
OnPropertyChanged("UserId");
}
}
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
OnPropertyChanged("FirstName");
}
}
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
OnPropertyChanged("LastName");
}
}
public string City
{
get
{
return city;
}
set
{
city = value;
OnPropertyChanged("City");
}
}
public string State
{
get
{
return state;
}
set
{
state = value;
OnPropertyChanged("State");
}
}
public string Country
{
get
{
return country;
}
set
{
country = value;
OnPropertyChanged("Country");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
View :- MainPage.xml
<Window x:Class="TestApplication.View.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestApplication" Height="485" Width="525">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="UserGrid" Grid.Row="1" Margin="4,178,12,13" ItemsSource="{Binding Users}" >
<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>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.UserId}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.FirstName}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,62,0,0" Name="txtLastName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.LastName}" />
<Label Content="UserId" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
<Label Content="Last Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,60,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="First 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="310,40,0,0" Name="btnUpdate"
VerticalAlignment="Top" Width="141"
Command="{Binding Path=UpdateCommad}" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,143,0,0" x:Name="txtCity" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.City, ElementName=UserGrid}" />
<Label Content="Country" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,141,0,0" x:Name="label2_Copy" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,88,0,0" x:Name="txtCountry" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.Country, ElementName=UserGrid}" />
<Label Content="City" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,86,0,0" x:Name="label2_Copy1" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,115,0,0" x:Name="txtSTate" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.State, ElementName=UserGrid}" />
<Label Content="State" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,113,0,0" x:Name="label2_Copy2" VerticalAlignment="Top" />
</Grid>
</Window>
View Model : UserViewMOdel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using TestApplication.Model;
using System.Windows.Input;
namespace TestApplication.ViewModel
{
class UserViewModel
{
private IList<User> _UsersList;
public UserViewModel()
{
_UsersList = new List<User>
{
new User{UserId = 1,FirstName="Raj",LastName="Beniwal",City="Delhi",State="DEL",Country="INDIA"},
new User{UserId=2,FirstName="Mark",LastName="henry",City="New York", State="NY", Country="USA"},
new User{UserId=3,FirstName="Mahesh",LastName="Chand",City="Philadelphia", State="PHL", Country="USA"},
new User{UserId=4,FirstName="Vikash",LastName="Nanda",City="Noida", State="UP", Country="INDIA"},
new User{UserId=5,FirstName="Harsh",LastName="Kumar",City="Ghaziabad", State="UP", Country="INDIA"},
new User{UserId=6,FirstName="Reetesh",LastName="Tomar",City="Mumbai", State="MP", Country="INDIA"},
new User{UserId=7,FirstName="Deven",LastName="Verma",City="Palwal", State="HP", Country="INDIA"},
new User{UserId=8,FirstName="Ravi",LastName="Taneja",City="Delhi", State="DEL", Country="INDIA"}
};
}
public IList<User> Users
{
get { return _UsersList; }
set { _UsersList = value; }
}
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
}
set
{
mUpdater = 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
}
}
}
You need to initialize the DataContext of your View. You can do this in the ctor of your MainPage.
I assume here that the UserViewModel is the ViewModel for your MainPage.
public MainPage() {
InitializeComponents();
this.DataContext = new UserViewModel();
}