0
 <DataGrid Name="employeesDataGrid" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn
                xmlns:myconv="clr-namespace:MyProject.Converters"
                Binding="{Binding enabled, Converter={myconv:IntToBool}}"
                Header="Enabled">
                <DataGridCheckBoxColumn.CellStyle>
                    <Style>
                        <EventSetter Event="CheckBox.Checked" Handler="OnChecked" />
                    </Style>
                </DataGridCheckBoxColumn.CellStyle>
            </DataGridCheckBoxColumn>
            <DataGridTextColumn 
                Binding="{Binding proxyFor}"
                Header="Proxy For"
                />
        </DataGrid.Columns>
    </DataGrid>

Code Behind

    private void OnChecked(Object sender, RoutedEventArgs e)
    {
        // Not sure what to do here.
    }

How do I keep track of whats changed in the DataTable or the selected row?

I am loaded this at Initialize() with the following code

        using (OleDbConnection con = new OleDbConnection(connectionString))
        {
            dt = new DataTable("accesscontrol");

            CmdString = "SELECT proxyFor, enabled FROM accesscontrol WHERE currentlyLoggedOnUser = @userName";
            OleDbCommand cmd = new OleDbCommand(CmdString, con);
            cmd.Parameters.AddWithValue("userName", Environment.UserName);
            using (adapter = new OleDbDataAdapter(cmd))
            {
                adapter.Fill(dt);
            }                    
            employeesDataGrid.ItemsSource = dt.DefaultView;
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
software is fun
  • 7,286
  • 18
  • 71
  • 129

3 Answers3

2

This is what I would do; I would add an intermediate step in between the data loading. I would transfer the data that you have loaded into a Model which would have the properties corresponding to the types I need and do the binding against the models. All of the changes that are being made would be preserved in the models you have created.

This will give you some significant advantages, in the fact that you will not have to keep track of the individual changes and organize them in such a fashion. This will also allow you to keep the UI interaction "cleaner" per say. Making the code more readable and concise.

If you are running a MSSQL Server you might want to have a look into Entity Framework. It would make this work much easier.

This will be roughly how you translate your models based off of the OleDBConnection documentation

//this list should be declared out of this scope and be declared in the main class
List<YourDbModel> models = new List<YourDbModel>();   
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
    OleDbCommand command = new OleDbCommand(queryString, connection);
    connection.Open();
    OleDbDataReader reader = command.ExecuteReader();
    while (reader.Read())
    {
        // translate the properties of your query to your model.
        YourDbModel model = new YourDBModel();
        model.property = reader[0].ToString();
        models.add(model);
    }
    reader.Close();
}   

You then need to set your itemsource for the DataTable. Currently you are doing this manually I prefer MVVM style but for consistency I will do it your way.

Initilize();
employeesDataGrid.ItemSource = models;

Now you will need to reconfigure your columns to match the newly created models. After you set your binding that go from the columns to the properties of each individual model, the changes will automatically reflect from your to your models. If you want to reflect the changes from your model to your view you will need to have a proper viewmodel.

I would also like to urge you to investigate the MVVM way of doing binding, this makes WPF significantly easier and more fun to work with.

Matt Wilkinson
  • 592
  • 2
  • 13
  • 1
    To expand on what Matt said I created a small application to demonstrate this. I pasted the code into Gist. I also used the Nuget package Prim6 & Prism6 WPF for using DelegateCommands. Take a look here - https://gist.github.com/TravisBoatman/d8d6293278ff77374400b391e4f6bece – Travis Boatman Apr 25 '16 at 16:34
  • It needs to be Microsoft Access. SQL Server would be better but they will never pay for it. They already denied using SQL Server Express – software is fun Apr 25 '16 at 17:42
  • @MattWilkinson What you're suggesting is to create another file that is my Data Model? but you aren't explaining how everything gets glued back together. I am fairly new at WPF and I have no problem switching over to your idea if you could share how the commits are done with the database. – software is fun Apr 25 '16 at 17:48
  • @softwareisfun I edited the answer to go in a bit more detail, but you might have a bit of trouble getitting it to work. Also Travis had a really good example in his gist. they might give a cleaner representation of the MVVM framework. I hope this helps. – Matt Wilkinson Apr 25 '16 at 18:07
  • @softwarisfun Also, not really another file, just another class. This class is essentially your model that represents the row of data on the table. – Matt Wilkinson Apr 25 '16 at 18:10
  • Thanks. I was doing it that way before before someone on SO told me to go this other route. SO I switched. I thought using ItemsSource would be the way to go but i am not an expert so when someone offered me help and chose to go another route, I took it – software is fun Apr 25 '16 at 18:11
  • @softwareisfun yeah The other way will get you to view the data really quick, however it is filled with short comings. SO is dependent on the question and it is hard to put the entire scope of the problem in a brief description that will be answered. I hope this helps, cheers. – Matt Wilkinson Apr 25 '16 at 18:13
  • Can you just show me what YourDbModel would look like? Is the model the data we are displaying or does it mirror the SQL returned query. – software is fun Apr 25 '16 at 18:14
  • @softwareisfun Yeah Sure here is a basic model. https://gist.github.com/ScFix/86121d50210baeffba75e4ba19cc7263 – Matt Wilkinson Apr 25 '16 at 18:19
  • I created the Model class, set the ItemSource and during the code execution, I F11 each value. my WPF DataGridView shows no data. Do I need to change my XAML? – software is fun Apr 25 '16 at 19:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110183/discussion-between-software-is-fun-and-matt-wilkinson). – software is fun Apr 25 '16 at 19:40
  • I found it to be a XAML issue. I updated my Bindings to Binding="{Binding isBool}" and Binding="{Binding Name}" and now my data showed up. When I uncheck or check the box, it doesnt push those changes back to the the database. Can you steer me in the correct direction please? – software is fun Apr 25 '16 at 19:45
2

The proper way to handle this would be to use databinding.

  1. Create your data models (they should have a boolean property that you can bind your check box to)
  2. Put said data models into an observable collection
  3. Bind your datagrid to your observable collection

When your check box is checked or unchecked the setter in the model will trigger. This can then be used to run what ever operations you'd like.

I could give you an exact example of this but there is maybe a billion of them already in existence. So to prevent further repetitiveness on the internet here's a few links...

What Is DataBinding

Datagrid binding in WPF

WPF checkbox binding

Community
  • 1
  • 1
DotNetRussell
  • 9,716
  • 10
  • 56
  • 111
  • Once you have an ObservableCollection, how do you push the changes back to the database? – software is fun Apr 25 '16 at 20:15
  • @softwareisfun The same way you got the data out of the database, just in reverse – DotNetRussell Apr 26 '16 at 13:19
  • I know how to perform an update Query to an SQL database. I suppose I wasnt clear. How would I tie my SQL Update CMD to the event checkbox on/off and how would I get the data from the row that is affected? – software is fun Apr 26 '16 at 19:08
  • @softwareisfun I would look into my answer a little more. You don't use the event at all with DataBinding. When you check the check box, the setter is called on the boolean in your C#. This is where you can invoke a save to the database. – DotNetRussell Apr 26 '16 at 19:12
  • Is the EventSetter going to trigger the event handler to execute the code. but how would I know what the parameters are in my SQL Update. UPDATE table name SET enabled=? WHERE proxyFor=? AND currentlyLoggedOnUser=? (this one I can get from Environment.Username). I have no idea how to get the values for the DataGrid that I am attempting to change – software is fun Apr 26 '16 at 19:16
  • Once again, please do some research on databinding. With databinding you use MVVM pattern. This pattern, Model View ViewModel means that your models are bound to the datagrid and are updated as you update the date WITHOUT events and event handlers. – DotNetRussell Apr 26 '16 at 20:18
-1

No need to detect if your CheckBox is bound to a Boolean Property of your DataSource. Property will be updated automatically.

AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38