Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# ПІДРУЧНИКИ / c# / Manning - Windows.forms.programming.with.c#.pdf
Скачиваний:
108
Добавлен:
12.02.2016
Размер:
14.98 Mб
Скачать

Set the version number of the MyPhotoAlbum library to 17.3.

SUPPORT THE IEDITABLEOBJECT INTERFACE IN THE PHOTOGRAPH CLASS

 

Action

Result

 

 

 

1

In the Photograph.cs code

using System.ComponentModel;

 

window, indicate that we will

 

 

use members of the

 

 

System.ComponentModel

 

 

namespace.

 

 

 

 

2

Add IEditableObject to the

public class Photograph : IDisposable,

 

list of supported interfaces for

IEditableObject

 

this class.

{

 

. . .

 

 

 

 

 

3

Add internal fields to track when

private bool _modified;

 

the object is in an editable state

private bool _editing;

 

or has been modified.

 

 

 

 

4

Initialize these fields in the

public Photograph(string fileName)

 

constructor.

{

 

 

. . .

 

 

_modified = false;

 

 

_editing = false;

 

 

}

 

 

 

5

Reset these values when the

public void Write(StreamWriter sw)

 

photograph is saved into a

{

 

StreamWriter object.

. . .

 

_modified = false;

 

 

 

 

_editing = false;

 

 

}

 

 

 

6

Add internal fields to record the

private string _editCaption;

 

existing values of the four

private string _editPhotographer;

 

modifiable properties.

private DateTime _editDateTaken;

 

private string _editNotes;

 

 

 

 

 

7

Implement the BeginEdit

public void BeginEdit()

 

method.

{

 

How-to

if (!_editing)

 

{

 

If editing is not already enabled,

_editCaption = Caption;

 

record the current values and

_editDateTaken = DateTaken;

 

_editPhotographer = Photographer;

 

enable editing.

 

_editNotes = Notes;

 

Note: Ideally, we would permit

_editing = true;

 

}

 

nesting of these calls. In this

 

}

 

example we will avoid this addi-

 

 

tional complexity.

 

 

 

 

8

Implement the CancelEdit

public void CancelEdit()

 

method.

{

 

How-to

if (_editing)

 

{

 

If editing is enabled, restore the

Caption = _editCaption;

 

recorded values and disable

Photographer = _editPhotographer;

 

DateTaken = _editDateTaken;

 

editing.

 

Notes = _editNotes;

 

 

_editing = false;

 

 

}

 

 

}

 

 

 

EDITABLE OBJECTS

583

SUPPORT THE IEDITABLEOBJECT INTERFACE IN THE PHOTOGRAPH CLASS (continued)

 

Action

Result

 

 

 

9

Implement the EndEdit

public void EndEdit()

 

method.

{

 

How-to

if (_editing)

 

{

 

If editing is enabled, record

_modified |= ((Caption != _editCaption)

 

whether the data has been

|| (Photographer != _editPhotographer)

 

|| (DateTaken != _editDateTaken)

 

modified and disable editing.

 

|| (Notes != _editNotes));

 

 

_editing = false;

 

 

}

 

 

}

 

 

 

10

Also add a HasEdits property to

public bool HasEdits

 

report whether the object has

{

 

been modified.

get { return _modified; }

 

}

 

 

 

 

 

The IEditableObject interface is now fully implemented. Another useful change in our library is the ability to identify if a PhotoAlbum, and not just a Photograph, has been modified. We can do this by continuing the previous steps to add a

HasEdits method in the PhotoAlbum class.

ADD A HASEDITS PROPERTY TO THE PHOTOALBUM CLASS

 

Action

Result

 

 

 

11

In the PhotoAlbum.cs code

public bool HasEdits

 

window, Implement a HasEdits

{

 

method in this class.

get

 

{

 

 

 

How-to

foreach (Photograph p in this)

 

Use the Photograph.HasEdits

{

 

if (p.HasEdits)

 

method to determine the

 

return true;

 

appropriate result.

}

 

 

// No edits found

 

 

return false;

 

 

}

 

 

}

 

 

 

The MyPhotoAlbum library is ready to go. Make sure the library compiles with no errors. The next step is to make use of these changes in our MyAlbumData application. This is taken up in the next section.

17.3.3USING EDITABLE OBJECTS

Typically, you do not actually use the editable object methods directly. These are used

internally by Windows Forms as required for the task at hand. In this case, our DataGrid control automatically recognizes that our PhotoAlbum object supports this interface, and calls BeginEdit whenever a user initiates a change to a row in the grid. If a user cancels an edit by pressing the Esc key, then CancelEdit is called. When the

584

CHAPTER 17 DATA BINDING

user finishes an edit by pressing the Enter key or selecting an alternate row, the EndEdit method is invoked. The EndEdit method makes the changes to the object permanent within the object itself.

In most applications, there is an operation or class that coordinates the in-mem- ory version of an object with the permanent version of an object. In our application, the in-memory version is our PhotoAlbum class, while the permanent version is our album file. The Save method updates the album file with the version in memory, while the Open method fills the in-memory version with the recorded version in the album file.

This is true in the System.Data namespace as well. While we have avoided discussing this namespace in any real depth, it is useful to understand how the classes in this namespace relate to our discussion. The abstract DataAdaptor class is the coordinator between the in-memory version of the database, typically a DataSet instance, and the permanent version is an external database. The DataAdaptor class provides a Fill method to populate a DataSet with the external values, and an Update method to save modifications in the DataSet into the external database.

For our purposes, we have provided the HasEdits method in our in-memory objects in order to identify whether any changes must be saved into the album file. We can do this in the SelectedIndexChanged event handler before the new album is bound to our data grid.

The following table details the steps required to save our PhotoAlbum instance into its associated album file:

Set the version number of the MyAlbumData application to 17.3.

 

SAVE A MODIFIED ALBUM

 

 

 

 

Action

Result

 

 

 

1

In the MainForm.cs window,

private void SaveChanges()

 

create a new SaveChanges

{

 

method to store any changes to

if (_album.HasEdits)

 

{

 

the displayed album into the

 

DialogResult result = MessageBox.Show(

 

album file.

"Do you wish to save your changes "

 

How-to

+ "to the album \'" + _album.Title

 

+ "\'?",

 

a. If the album has been modi-

"Save Changes?",

 

fied, prompt the user to see

MessageBoxButtons.YesNo,

 

MessageBoxIcon.Question);

 

if he or she wishes to save

 

if (result == DialogResult.Yes)

 

the changes.

_album.Save();

 

b. If yes, then save the album in

}

 

}

 

the existing album file.

 

 

 

 

 

EDITABLE OBJECTS

585

SAVE A MODIFIED ALBUM (continued)

 

Action

Result

 

 

 

2

Use this new method when the

private void cmbxAlbum_SelectedIndexChanged

 

user selects a new album in the

(object sender, System.EventArgs e)

 

ComboBox control.

{

 

string albumFile

 

 

 

 

= cmbxAlbum.SelectedItem.ToString();

 

 

if (_album != null)

 

 

{

 

 

SaveChanges();

 

 

_album.Dispose();

 

 

}

 

 

_album.Clear();

 

 

try

 

 

. . .

 

 

}

 

 

 

3

Also make sure any changes are

protected override void OnClosing

 

saved when the application

(CancelEventArgs e)

 

exits.

{

 

SaveChanges();

 

 

 

 

base.OnClosing(e);

 

 

}

 

 

 

With these modifications, our edits are now saved. Compile and run to verify that the application works as advertised.

More .NET Additional information on the DataGrid control is available in the .NET documentation and in various sample programs freely available on the Internet. One such example is the CdrCatalog program built by Andrew Skowronski that is available at http://cdrcatalog.sourceforge.net/. This program manages offline media, such as a collection of recordable compact discs, and makes use of a number of Windows Forms classes in addition to the DataGrid control. The data source used by this application is a DataSet object loaded from a local XML file.

17.4SIMPLE DATA BINDING

Binding data to a data grid is referred to as complex data binding, since multiple values are bound to a single control. Complex data binding also refers to binding objects to a list control, such as a list box or combo box. For example, if we had actually implemented the AlbumCollection class I keep mentioning to contain an array of PhotoAlbum objects, then the line to assign the DataSource for our combo box could instead be written as:

cmbxAlbum.DataSource = myAlbumCollection;

cmbxAlbum.DataMember = "FileName";

This would display the collection of PhotoAlbum objects in the myAlbumCollection variable in the cmbxAlbum combo box, using the FileName property as the

586

CHAPTER 17 DATA BINDING

name to display. The result would be the same as that which currently appears in our application. This type of binding to a list control can also be done with database objects, such as binding the entries in a ListBox control to the set of customer names found in one column of a database table.

Simple data binding is used for binding single property values to a specific data source. This type of binding is supported by the Control class directly, and is therefore inherited by and available in all controls in Windows Forms. The concepts and techniques for so-called simple data binding are fairly identical to those we have already discussed for the DataGrid control.

In this section we will alter our application to permit some simple data binding to a photo album. We will see how to perform simple binding; update bound controls dynamically, including the image associated with a photograph; and save changes to bound controls.

17.4.1ALTERING THE MYALBUMDATA APPLICATION

Before we get into the details of exactly how simple data binding is performed, let’s whip through some changes to our MyAlbumData application in preparation for this discussion. The change we will make is to place our existing DataGrid control within a TabPage object, and add a new tab to display the Photograph information for an album one photo at a time. Figure 17.6 shows the modified application we will build throughout this and the next few sections.

Figure 17.6 These controls on the Photo tab are bound to their corresponding values in a Photograph object.

SIMPLE DATA BINDING

587

Соседние файлы в папке c#