Whats wrong in my data binding ?
I am MVVM beginner and i have to take some data from user in textbox and then display that data in data grid, there are 3 textboxes and corresponding 3 textboxes respectively. And a button which on click must save the entered data to the data grid columns.
I have everything working except the data is not updated to datagrid.
Here is my View:
< Window x: Class = "DatagRidBelowTextUpdate.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 EditModel.TextName}"
Height = "20"
Width = "80"
HorizontalAlignment = "Center" > < /TextBox> < TextBox Grid.Column = "1"
Grid.Row = "1"
Text = "{Binding EditModel.RollNumber}"
Height = "20"
Width = "80" > < /TextBox> < TextBox Grid.Column = "1"
Grid.Row = "2"
Text = "{Binding EditModel.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, Mode=TwoWay}"
Width = "150" > < /DataGridTextColumn> < DataGridTextColumn Header = "Rollnumber"
Binding = "{Binding DgRollnumber, Mode=TwoWay}"
Width = "150" > < /DataGridTextColumn> < DataGridTextColumn Header = "Class"
Binding = "{Binding DgClass , Mode=TwoWay}"
Width = "150" > < /DataGridTextColumn> < /DataGrid.Columns> < /DataGrid> < /Grid> < /Grid> < /Window>
My ViewModel:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
namespace DatagRidBelowTextUpdate {
class ViewModel {
private RelayCommand saveStudentRecord;
private Model editModel;
public bool canExecute {
get;
set;
}
public ObservableCollection < Model > DGrid;
private string dgName;
private string dgRollnumber;
private string dgClass;
public string DgName {
get {
return dgName;
}
set {
dgName = value;
PropertyChangedEventArgs("DgName");
}
}
public string DgRollnumber {
get {
return dgRollnumber;
}
set {
dgRollnumber = value;
PropertyChangedEventArgs("DgRollnumber");
}
}
public string DgClass {
get {
return dgClass;
}
set {
dgClass = value;
PropertyChangedEventArgs("DgClass");
}
}
public Model EditModel {
get {
return editModel;
}
set {
editModel = value;
PropertyChangedEventArgs("EditModel");
}
}
public ViewModel() {
editModel = new Model();
canExecute = true;
DGrid = new ObservableCollection < Model > ();
}
public RelayCommand SaveStudentRecord {
get {
return saveStudentRecord = new RelayCommand(() => MyAction(), canExecute);
}
}
private void MyAction() {
string chck1 = editModel.TextName; //TextName; //I see on debugging that TextName contains the text entered so how to add this text to Datagrid column
string chck2 = editModel.Class;
string chck3 = editModel.RollNumber;
// DGrid = new ObservableCollection<Model>();
// dgClass = editModel.Class;
// dgName = editModel.TextName;
// dgRollnumber = editModel.RollNumber;
DGrid.Add(editModel);
// editModel = new Model();
}
public event PropertyChangedEventHandler PropertyChanged;
private void PropertyChangedEventArgs(string propertyName) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
My Model:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DatagRidBelowTextUpdate {
class Model {
private string textName;
private string rollNumber;
private string cclass;
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 {
cclass = value;
PropertyChangedEventArgs("Class");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void PropertyChangedEventArgs(string propertyName) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
What is wrong in the binding that it do not update the datagrid in button click MyAction()
EDIT:
(I dont want to use DGrid.Add(editModel); and i dont want to do AutoGenrateColumns to True, because o have to understand the binding concept of individual UI).I mean i wish to bind the columns in datagrid manually in xaml and then assign the textboxes data using textbox binded variables to the datagrid binded variables, i mean something like dgName=editModel.Name
on button click.
Viem Model is:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
namespace DatagRidBelowTextUpdate
{
class ViewModel :INotifyPropertyChanged
{
private RelayCommand saveStudentRecord;
private Model editModel;
public bool canExecute { get; set; }
public ObservableCollection<Model> DGrid { get; set; }
private string dgName{ get; set; }
private string dgRollnumber { get; set; }
private string dgClass { get; set; }
public string DgName
{
get
{
return dgName;
}
set
{
dgName = value;
PropertyChangedEventArgs("DgName");
}
}
public string DgRollnumber
{
get
{
return dgRollnumber;
}
set
{
dgRollnumber = value;
PropertyChangedEventArgs("DgRollnumber");
}
}
public string DgClass
{
get
{
return dgClass;
}
set
{
dgClass = value;
PropertyChangedEventArgs("DgClass");
}
}
public Model EditModel
{
get
{
return editModel;
}
set
{
editModel = value;
PropertyChangedEventArgs("EditModel");
}
}
public ViewModel()
{
editModel = new Model();
canExecute = true;
}
public RelayCommand SaveStudentRecord
{
get { return saveStudentRecord = new RelayCommand(() => MyAction(), canExecute); }
}
private void MyAction()
{
dgClass = editModel.Class;
dgName = editModel.TextName;
dgRollnumber = editModel.RollNumber;
//according to my understanding , the data in editModel.Class must be added to dgClass in View, obsolutley i am wrong, please correct me.
}
public event PropertyChangedEventHandler PropertyChanged;
private void PropertyChangedEventArgs(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
View is:
<Window x:Class="DatagRidBelowTextUpdate.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 EditModel.TextName}" Height="20" Width="80" HorizontalAlignment="Center"></TextBox>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding EditModel.RollNumber}" Height="20" Width="80"></TextBox>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding EditModel.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, Mode=TwoWay}" AutoGenerateColumns="False">
<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>