简体   繁体   中英

C# WPF Datagrid using CellEditEnding Update Database

Hi everyone am working on C# WPF Application in which I need Update Data on the server side by edit cell value(on pressing Enter).here is my code for(how am working to assign data to datagrid ). I don't have an idea how do I update values within the datagrid and which event will be used for that Thank You (^_^)

Backend

con.Open();
SqlDataAdapter adapter = new SqlDataAdapter("select r.id,r.datee,r.time,c.name,r.description,r.vanda,r.bag,r.price,r.credit,r.debit from records as r, customer as c where r.cusid = c.id and c.name = '" + name + "' and r.datee between '" + startdate.Text + "' and '" + enddate.Text + "' order by r.datee asc", con);
DataSet ds = new DataSet();
adapter.Fill(ds);
data.DataContext = ds.Tables[0];
con.Close();

Frontend

<DataGrid x:Name="data" ItemsSource="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="422" Width="1086" IsReadOnly="True" Margin="0,100,0,0" TabIndex="10"/>

If you are using a dataset then I believe you end up with TableAdapter for each of the tables. The TableAdapter class has an update method that will go through row by row of the table in the dataset (the local copy of the data that originally came from the database) and do the delete, update, create necessary for each of them. If there are related tables then generally they are taken care of too. The DatasetDesigner in VisualStudio will create the TableAdapters for you. In MVVM you would have a ViewModel that knows of the DataSet, Tables, and TableAdapters, and can update as necessary or desired based on what happens in the View.

More specifically, I use Linq to SQL which gives me a DataContext (similar to a dataset, but for a different approach to getting full CRUD on a database) In the ViewModel you first set up your datacontext, then you can bind an ICommand for onRowEditEnding to execute your own handler, which calls the DataContext method SubmitChanges() which updates all of the rows in the datagrid:

public partial class MyViewModel : ViewModelBase
{
    static MyDataContext _dataDC = new MyDataContext();//This class is from the Visual Studio DataDesigner Magic
    //There is a constructor here as well . . . skipped for brevity
    private ICommand _onRowEditEnding;
    public ICommand OnRowEditEnding
    {
        get { return _onRowEditEnding; }// set as new DelegateCommand(DocumentRowEditEvent) in the VM Constructor
    }

    public void DocumentRowEditEvent()
    {
         _dataDc.SubmitChanges(); //Refreshes the view as well
         return;
    }
}

and the ViewModelBase class is:

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChangedEvent(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Here is the View (Window XAML):

<Window x:Name="MyWin" x:Class="MYNAMESPACE.Windows.WinMyWin"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ViewModel="clr-namespace:MYNAMESPACE.ViewModel"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    Title="Files Returned" Height="400" Width="900">
  <Grid DataContext="{Binding}">
    <DataGrid  AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch"
               ItemsSource="{Binding DataContext.oFRet.View, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
               SelectedItem="{Binding DataContext.CurrentReturn, RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="rIDColumn" Binding="{Binding UID}" Header="ID" Width="35"/>
            <DataGridTextColumn x:Name="xIDColumn" Binding="{Binding xID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="xID" Width="35"/>
            <DataGridTextColumn x:Name="rDocumentNumberColumn" Binding="{Binding DocumentNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Document Number" Width="255"/>
            <DataGridTextColumn x:Name="rREVColumn" Binding="{Binding REV}" Header="REV" Width="45"/>
            <DataGridTextColumn x:Name="rCODEColumn" Binding="{Binding CODE}" Header="CODE" Width="45"/>
            <DataGridTextColumn x:Name="rTNTransColumn" Binding="{Binding RTNTrans}" Header="RTN Transmittal" Width="215"/>
            <DataGridTextColumn x:Name="rFileNameColumn" Binding="{Binding FileName}" Header="FileName" Width="255"/>
        </DataGrid.Columns>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="RowEditEnding">
                <i:InvokeCommandAction Command="{Binding DataContext.OnRowEditEnding, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </DataGrid>
  </Grid>
</Window>

And the CodeBehind for the Window:

public partial class WinMyWin : Window
{
    public WinMyWin(MyViewModel vm)
    {
        InitializeComponent();
        DataContext = vm;
    }

}

What is missing is the ObservableCollection that is bound to the datagrid. It is part of the ViewModel, and will use (in my case) Linq to SQL to grab the data from the database when it is constructed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM