views:

11448

answers:

6

My scenario is:

I have a WPF Window with 3 data-bound text boxes

SettingsUI : Window

<Grid Name="SettingsUIGrid1">
<TextBox Text="{Binding Path =val1}" ....
<TextBox Text="{Binding Path =val2}" ....
<TextBox Text="{Binding Path =val3}" ....
</Grid>

In the constructor I do this:

SettingsUIGrid1.DataContext = coll[0]; // collection first value

When the Cancel button is clicked, I close my window:

private void btnCancel_Click(object sender, RoutedEventArgs e) {
Close();
}

When I click the Show button, is shows values from the DB in text boxes, if user changes a text box value, and reloads the window the new value is displayed not the old one. Can someone suggest what to do to reload the values again and clear the in memory object?

A: 

I would suggest putting some code into your cancel button click event to check whether any of the data has been changed from what was initially loaded as I am assuming that if they don't click cancel the other button would be save/ok meaning that the data would be committed to the database.

What is coll?

if it is a DataTable then you could use this:

private static bool DataRowReallyChanged(DataRow row)
    {
        if (row == null)
        {
            return false;
        }

        if (!row.HasVersion(DataRowVersion.Current) || (row.RowState == DataRowState.Unchanged))
        {
            return false;
        }

        foreach (DataColumn c in row.Table.Columns)
        {
            if (row[c, DataRowVersion.Current].ToString() != row[c, DataRowVersion.Original].ToString())
            {
                return true;
            }
        }

        return false;
    }

then simply add a call into the cancel button event like:

if (DataRowReallyChanged((DataRow)SettingsUIGrid1.DataContext))
{
     ((DataRow)SettingsUIGrid1.DataContext).RejectChanges();
}

I hope this helps. If you are not using a DataTable then let me know what you are using and ill see if i can help further.

Bijington
+3  A: 

The Binding works two way: it takes the value and sets it editable in the textbox, and if the value changes, it updates the original object's value...

If you only wish to show the data, you can use the Mode=OneTime option in the Binding

{Binding Path =val1, Mode=OneTime}

This will only evaluate the data once..

If you do need to modify the data, make sure you clone or use another object for your datasource property.. This way you can discard the datasource object if it is no longer needed...

HTH

Arcturus
A: 
coll is Collection<ImportSettings>
A: 

Ok sorry just to clarify everything you are loading the collection from a database and populating your textboxes, the user can then modify these values which depending on whether they click save/ok or cancel will save or not save the changes respectively. if this is the case then I would use arcturus's solution.

I used my solution as we created our own 'typed' DataSets which implemented IEnumerable to make life easier than having to keep populating Collections. Although I am starting to wish we used LINQ.

Bijington
A: 

I did it this way -> added a text box more, binded it with ID of the object (only one object should be there since I have only one record that stores all my settings), and used ,Mode=OneTime for all binding.....so if user saves it will update the existing object.Cancel will work now.....................whew!

A: 

If you don't want to modify your data, you can set you binding to be OneWay:

<Grid Name="SettingsUIGrid1">
<TextBox Text="{Binding Path =val1, Mode=OneWay}" ....
<TextBox Text="{Binding Path =val2, Mode=OneWay}" ....
<TextBox Text="{Binding Path =val3, Mode=OneWay}" ....
</Grid>
sacha