destro
Well-known member
- Joined
- Mar 28, 2020
- Messages
- 46
- Programming Experience
- 1-3
I have a Datagrid bound to Datatable through Dependency property. I am unable to retrieve changes I make in datagrid even when I have set binding mode as two way.
What are the best possible ways to update changes back to Source DataTable when dataGrid is edited?
I know I can use DataAdapter.Update() to commit changes to database but that's not what I am asking so don't confuse. I want to know effecient ways to save changes back to ViewModel's DataTable Property.
The Datatable property is populated at runtime as:
The custom usercontrol named StudentsGrid is just a datagrid inside a grid:
and this is the code-behind of above xaml where dependency property is registered:
The final is MainWindow which binds the StudentsTable property to the custom user control:
The datacontext of mainWindow is set in code-behind's constructor as:
This is the result I get:
What are the best possible ways to update changes back to Source DataTable when dataGrid is edited?
I know I can use DataAdapter.Update() to commit changes to database but that's not what I am asking so don't confuse. I want to know effecient ways to save changes back to ViewModel's DataTable Property.
The Datatable property is populated at runtime as:
C#:
class EmployeeViewModel : INotifyPropertyChanged
{
private DataTable _dt = new DataTable();
public event PropertyChangedEventHandler PropertyChanged;
public DataTable _Table
{
get
{
return _dt;
}
set
{
_dt = value;
OnPropertyChanges(nameof(_Table));
}
}
private void OnPropertyChanges(String propertyName)
{
var h = PropertyChanged;
if (h != null)
h(this, new PropertyChangedEventArgs(propertyName));
// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public EmployeeViewModel()
{
ReadData();
}
public void ReadData()
{
string cs = ConfigurationManager.ConnectionStrings["Employee.mdf"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
SqlDataAdapter da = new SqlDataAdapter("Select * from tblStudents", con);
DataSet set = new DataSet();
da.Fill(set, "Students");
_Table = set.Tables[0];
}
}
}
The custom usercontrol named StudentsGrid is just a datagrid inside a grid:
C#:
<UserControl x:Class="ADO.Net_Practice.StudentsGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ADO.Net_Practice"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<DataGrid ItemsSource="{Binding StudentsTable, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:StudentsGrid}}, Mode=TwoWay}" Margin="10,10,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" MinHeight="200"/>
</Grid>
C#:
/// <summary>
/// Interaction logic for StudentsGrid.xaml
/// </summary>
public partial class StudentsGrid : UserControl
{
public StudentsGrid()
{
InitializeComponent();
}
public DataTable StudentsTable
{
get { return (DataTable)GetValue(StudentsTableProperty); }
set { SetValue(StudentsTableProperty, value); }
}
// Using a DependencyProperty as the backing store for StudentsTable. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StudentsTableProperty =
DependencyProperty.Register("StudentsTable", typeof(DataTable), typeof(StudentsGrid), new PropertyMetadata(new DataTable(), StudentsTablePropertyChanged));
private bool _updating;
private static void StudentsTablePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var st = d as StudentsGrid;
if(st!=null)
{
st.DataChanged();
}
}
private void DataChanged()
{
if (_updating)
return;
_updating = true;
_updating = false;
}
}
C#:
<Grid>
<local:StudentsGrid StudentsTable="{Binding _Table, Mode=TwoWay}"/>
</Grid>
C#:
DataContext = new EmployeeViewModel();