Valid C # Principle 38: use and support data binding)

Source: Internet
Author: User

Valid C # Principle 38: use and support data binding
Item 38: utilize and support data binding

Experienced windowsProgramWriteCodeYou are familiar with setting values from a control and storing values on the control:

Public form1: Form
{
Private mytype mydatavalue;
Private textbox textboxname;

Private void initializecomponent ()
{
Textboxname. Text = mydatavalue. Name;
This. textboxname. Leave + = new
System. eventhandler (this. onleave );
}

Private void onleave (Object sender, system. eventargs E)
{
Mydatavalue. Name = textboxname. text;
}
}

This is too simple, as you know, to repeat the code. The reason why I do not like repeated code is that there should be better methods. Yes, the. NET Framework supports data binding. It can map the attributes of an object to the properties of the control:

Textboxname. databindings. Add ("text", mydatavalue, "name ");

The above code binds the "name" attribute of the mydatavalue object to the "text" attribute of the textboxname control. There are two internal objects, bindingmanager and currencymanager, which implement transmission between controls and data sources. You may have seen an example of a structure, especially between dataset and DataGrid. You may have already done data binding. On the surface, you may have simply used the functions obtained from data binding. You can avoid repeated code writing through efficient data binding.

The complete data binding solution may take at least one book to explain, or two. Both windows and Web applications support data binding. I really want you to remember the core benefits of data binding. First, data binding is much easier than writing code by yourself. Second, you should try to use it when displaying text elements through attributes. It can be well bound. Third, in Windows Forms, data bound to multiple controls can be synchronized for relevant data source detection.

For example, if you want to display the text in red when the data is invalid, you may write the following code:

If (SRC. textisinvalid)
{
Textbox1.forecolor = color. Red;
} Else
{
Textbox1.forecolor = color. Black;
}

This is good, but you need to call this code whenever the source of the text changes. This may be when the user edits the text or the underlying data source changes. There are too many events to handle, and you may miss them in many places. However, when binding data, add an attribute to the src object and return the appropriate foreground color.

Another logic may be to set the value to the appropriate color based on the text message status:

Private color _ CLR = color. Black;
Public color foregroundcolor
{
Get
{
Return _ CLR;
}
}

Private string _ txttodisplay;
Public String text
{
Get
{
Return _ txttodisplay;
}
Set
{
_ Txttodisplay = value;
Updatedisplaycolor (istextvalid ());
}
}

Private void updatedisplaycolor (bool bvalid)
{
_ CLR = (bvalid )? Color. Black: color. Red;
}

Simply add and bind it to the text box:

Textbox1.databindings. Add ("forecolor ",
SRC, "foregroundcolor ");

After the data binding is configured, textbox1 draws the text in the correct color based on the internal source object value. In this way, you have greatly reduced the back-and-forth data transmission from the source data to the control. You no longer need to display different colors for different places to handle many events. Your data source object keeps track of the correct display of properties, while the Form Control controls data binding.

In this example, I demonstrated the Data Binding of Windows forms. The same principle applies to Web applications: You can bind data source attributes to web control attributes:

<Asp: textbox id = textbox1 runat = "server"
TEXT = "<% # SRC. Text %>"
Forecolor = "<% # SRC. foregroundcolor %>">

This means that when you create an application to display the type on the UI, you should add some required attributes to create and update your UI so that users can use it when necessary.

What if your object does not support the attributes you want? Then encapsulate it as what you want. See the following data structure:

Public struct implements alresults
{
Public decimal revenue
{
Get {return _ revenue ;}
}

Public int numberofsales
{
Get {return _ numsales ;}
}

Public decimal costs
{
Get {return _ cost ;}
}

Public decimal profit
{
Get {return _ revenue-_ cost ;}
}
}

You are required to display the information in a special format in a form. If the profit is negative, you must display the profit in red. If the salary is less than 100, you should display it in bold. If the overhead is more than 10 thousand (10 thousand), you should also display it in bold. The developer who created the externalresults structure did not add the UI function to this structure. This is probably the right option. financialresults should limit its functionality to store actual values only. You can create a new type that includes the UI formatting attributes and the original storage attributes in the externalresults structure:

Public struct implements aldisplayresults
{
Private transferalresults _ results;
Public registralresults results
{
Get {return _ results ;}
}

Public color profitforegroundcolor
{
Get
{
Return (_ results. Profit> = 0 )?
Color. Black: color. Red;
}
}

// Other formatting options elided
}

In this way, you create a simple data structure to help you bind your contained data structure:

// Use the same datasource. That creates one binding Manager
Textbox1.databindings. Add ("text", SRC, "results. Profit ");
Textbox1.databindings. Add ("forecolor", SRC, "profitforegroundcolor ");

I have created a read-only attribute to access the core financial data structure. This kind of structure does not work when you try to support read/write operations on data. The delealresults structure is a value type, which means that the accesser does not provide access to the bucket, but returns a copy. In this way, you are happy to return a copy, but such a copy cannot be modified in data binding. However, if you try to edit the data, the financialresults class should be a class rather than a structure (see principle 6 ). As a reference type, your accessors return an internal storage reference and can be edited by users. The internal structure must respond to changes to the stored data. Financialresults should trigger an event to tell other code about this status change.

One important thing to remember is to use the data source on all related controls in the same form. Use the datamember attribute to differentiate the properties displayed by each control. You can write the binding process like this:

// Bad practice: creates two binding managers
Textbox1.databindings. Add ("text", SRC. Results, "profit ");
Textbox1.databindings. Add ("forecolor", SRC, "rofitforegroundcolor ");

This will create two binding managers, one being the src object and the other being the SRC. Results object. Each data source is controlled by different binding managers. If you want the binding administrator to update all attributes when the data source changes, ensure that the data source is consistent.

You can use data binding on almost all windows and Web controls. The value displayed in the control, Font, read-only status, and even the position of the control can all be the objects for binding operations. My suggestion is to create a class or structure that contains data that is displayed in a certain style as required by some users. The data is used to update controls.

In addition, data binding often appears in dataset and datagrids in simple controls. This is very useful. You bind the DataGrid to the dataset, and all the values in the dataset are displayed. If your dataset has multiple tables, you can even navigate between them. Isn't that good?

Well, the following question is what to do if your dataset does not contain the fields you want to display. In this case, you must add a column to dataset. This column is used to calculate the values required in some UIS. If the value can be calculated using an SQL expression, dataset can be completed for you. The following code adds a column to the employees data table to display and format the name:

Datatable dt = data. Tables ["employees"];
DT. Columns. Add ("employeename ",
Typeof (string ),
"Lastname + ',' + firstname ");

By adding columns to dataset, you can add these columns to the DataGrid. The Object layer you created is the most important layer of the data storage object. It is used to create a data presentation layer for your users.
So far, this principle uses the string type. the. NET Framework can convert characters to numbers: it tries to convert users' input to the appropriate type. If it fails, the original value is restored. This can work, but the user has no feedback, and their output is quietly ignored. You can add feedback by handling the conversion events during the binding process. This event occurs when the bound administrator updates the value from the control to the data source. Parseeventargs contains the text entered by the user and the type it expects to be converted. You can capture this event and then complete your own notifications. You can also modify the data and use your own values to update the data:

Private void formpolicparse (Object sender, converteventargs E)
{
Try {
Convert. toint32 (E. value );
} Catch
{
MessageBox. Show (
String. Format ("{0} is not an integer ",
E. value. tostring ()));
E. value = 0;
}
}

You may also need to handle the format event. This Hook can format the data from the data source to the control. You can modify the value field of converteventargs to format the required string.

. NET provides a general framework that allows you to support data binding. Your job is to provide some special event handles for your applications and data. Windows Forms, web forms, and subsystems all contain a wide range of data binding functions. The Framework library already contains all the tools you need. Therefore, your UI code should describe the data source and the properties to be displayed in real, rules that must be followed when these elements are stored in the data source. You should focus on creating data types to describe the displayed parameters, and then bind winform and webform data to complete other tasks. Related code should not be written when data is transmitted from the user control to the data source ). In any case, data must be associated with the UI control from your business object to interact with the user. By creating a type layer and using the data binding concept, you can write less code .. The net framework has already handled the transfer work for you in both Windows and Web applications.

==========================================================

Item 38: utilize and support data binding
Experienced windows programmers are familiar with writing the code to place data values in controls and to store values from controls:

Public form1: Form
{
Private mytype mydatavalue;
Private textbox textboxname;

Private void initializecomponent ()
{
Textboxname. Text = mydatavalue. Name;
This. textboxname. Leave + = new
System. eventhandler (this. onleave );
}

Private void onleave (Object sender, system. eventargs E)
{
Mydatavalue. Name = textboxname. text;
}
}

 

It's simple, repetitive codeyou know, the kind you hate to write because there must be a better way. there is. the. net Framework supports data binding, which maps a property of an object to a property in the control:

Textboxname. databindings. Add ("text ",
Mydatavalue, "name ");

 

The previous Code binds the "text" property of the textboxname control to the "name" property of the mydatavalue object. internally, two objects, the bindingmanager and the currencymanager, implement the transfer of data between the control and the data source. you 've probably seen this construct in your samples, and you can use this parameter to perform special operations with datasets and datagrids. you 've also done simple binding to text boxes. you 've likely only scratched the surface of the capabilities you get from data binding. you can avoid writing repetitive code by utilizing data binding more than tively.

A full treatment of Data Binding wowould span at least one book, if not two. both Windows applications and Web applications support data binding. rather than write a complete treatise of data binding, I want to make sure you remember the key advantages of it. first, using data binding is much simpler than writing your own code. second, you shoshould use it for more than text itemsother display properties can be bound as well. third, on Windows Forms, Data Binding handles synchronizing multiple controls that examine related data sources.

For example, suppose you get a requirement to display the text in red whenever the data shows an invalid value. You cocould write the following snippet:

If (SRC. textisinvalid)
{
Textbox1.forecolor = color. Red;
} Else
{
Textbox1.forecolor = color. Black;
}

 

That's well and good, but you need to call that snippet of code whenever the text in your source changes. that cocould be when the user edits the text or when the underlying data source changes. there are a lot of events to handle and other places that you might miss. instead, use data binding. add a property in your src object to return the proper foreground color.

Other logic will set the value of that variable to the proper color based on the state of the text message:

Private color _ CLR = color. Black;
Public color foregroundcolor
{
Get
{
Return _ CLR;
}
}

Private string _ txttodisplay;
Public String text
{
Get
{
Return _ txttodisplay;
}
Set
{
_ Txttodisplay = value;
Updatedisplaycolor (istextvalid ());
}
}

Private void updatedisplaycolor (bool bvalid)
{
_ CLR = (bvalid )? Color. Black: color. Red;
}

 

Then simply add the binding to the text box:

Textbox1.databindings. Add ("forecolor ",
SRC, "foregroundcolor ");

 

When the data binding is configured, textbox1 will draw its text in the correct color, based on the internal value of the source object. you 've done more to decouple the control from the data source. instead of having multiple event handlers and multiple locations where the display color changes, you have two. your data source object keeps track of the properties that affect the proper display. your form controls the data binding.

Although the samples I 've shown are windows forms, the same principle works for Web applications: You can bind properties of data sources to a property in the web control as well:

<Asp: textbox id = textbox1 runat = "server"
TEXT = "<% # SRC. Text %>"
Forecolor = "<% # SRC. foregroundcolor %>">

 

This means that when you create the types that your application displays in its UI, you should add the necessary properties to create and update your UI in response to user needs.

What do you do if the objects you have don't support the properties you need? You wrap what you have and add what you need. Consider this data structure:

Public struct implements alresults
{
Public decimal revenue
{
Get {return _ revenue ;}
}

Public int numberofsales
{
Get {return _ numsales ;}
}

Public decimal costs
{
Get {return _ cost ;}
}

Public decimal profit
{
Get {return _ revenue-_ cost ;}
}
}

 

You have requirements to display these in a form with some special formatting notes. if the profit is negative, you must display the profit in red. if the number of sales drops below 100, it shoshould be bold. if the cost is abve 10,000, it shoshould be bold. the developer who created the specified alresults structure did not add UI capabilities into the structure. that was most likely the right choice. specified alresults shocould limit its capabilities to storing the actual values. you can create a new type to include the UI formatting properties with the original store properties in the same alresults structure:

Public struct implements aldisplayresults
{
Private transferalresults _ results;
Public registralresults results
{
Get {return _ results ;}
}

Public color profitforegroundcolor
{
Get
{
Return (_ results. Profit> = 0 )?
Color. Black: color. Red;
}
}

// Other formatting options elided
}

 

You have created a single data structure to facilitate data binding of your contained structure:

// Use the same datasource. That creates one binding Manager
Textbox1.databindings. Add ("text ",
SRC, "results. Profit ");
Textbox1.databindings. Add ("forecolor ",
SRC, "profitforegroundcolor ");

 

I 've created one read-only property that allows access to the core financial structure. that construct doesn't work if you intend to support read/write access to the data. the specified alresults struct is a value type, which means that the get accessor does not provide access to the existing storage; it returns a copy. this idiom has happily returned a copy that cannot be modified using data binding. however, if you intended editing, the specified alresults type wocould be a class, not a struct (see item 6 ). as a reference type, your get accessor returns a reference to the internal storage and wocould support edits by the user. the internal structure wowould need to respond to changes made to the internal storage. the specified alresults wowould raise events to your y other code of changes in state.

It's important to remember to use the data source for all related controls in the same form. use the datamember property to differentiate the Property Displayed in each control. you coshould have written the binding construct this way:

// Bad practice: creates two binding managers
Textbox1.databindings. Add ("text ",
SRC. Results, "profit ");
Textbox1.databindings. Add ("forecolor ",
SRC, "profitforegroundcolor ");

 

That wocould create two binding managers, one for the src object and one for the SRC. results object. each data source is managed by a different binding manager. if you want the binding manager to update all property changes when the data source changes, you need to make sure that the data sources match.

You can use data binding for almost any property of a Windows or web control. the values displayed in the control, the font, the read-only state, and even the location of the control can be the target of a binding operation. my advice is to create the class or struct that contains the values you need to display your data in the manner requested by your users. then use data binding to update the controls.

In addition to simple controls, Data Binding often involves datasets and datagrids. it's very powerful: You bind the DataGrid to the dataset, and all the values in the dataset are displayed. if your dataset has multiple tables, you can even navigate between tables. what's not to love?

Well, the problem arises if your data set does not contain the fields you want to display. in those cases, you must add a column to the dataset that computes the value needed for the user interface. if the value can be computed using a SQL expression, the dataset can compute the value for you. the following code adds a column N to the employees data table that displays a formatted version of the name:

Datatable dt = data. Tables ["employees"];
DT. Columns. Add ("employeename ",
Typeof (string ),
"Lastname + ',' + firstname ");

 

By adding columns to the dataset, you can add columns to the DataGrid. You build layers of objects on top of the stored data objects to create the data presentation you want to give the user.

all the items I showed you so far are string types. the framework does handle converting strings to numeric values: it tries to convert the user's input to the proper type. if that fails, the original value is restored. it works, but the user gets absolutely no feedback, their input is silently ignored. you add that feedback by processing the parse event from the binding context. that event occurs when the binding Manager updates the value in the data source from the value in the control. parseeventargs gives you the text typed by the user and the desired type to convert the text. you can trap this event and perform your own notification, even going so far as to modify the value and update the text with your own value:

Private void formpolicparse (Object sender, converteventargs E)
{
Try {
Convert. toint32 (E. value );
} Catch
{
MessageBox. Show (
String. Format ("{0} is not an integer ",
E. value. tostring ()));
E. value = 0;
}
}

 

You might also want to handle the format event. this is the hook that lets you format the data that comes from your data source and goes into the control. you can modify the value field of converteventargs to format the string that shocould be displayed.

The. net Framework provides the generic framework for you to support data binding. your job is to provide the specific event handlers for your application and your data. both the Windows Forms and web forms subsystems contain rich data-binding capabilities. the library already contains all the tools you need, so your UI code shoshould really be describing the data sources and properties to be displayed and what rules shoshould be followed when you store those elements back in the data source. you concentrate on building the data types that describe the display parameters, and the winforms and webforms Data Binding does the rest. there is no way around und writing the code that transfers values between the user controls and the data source objects. somehow, data must get from your business objects to the controls that your users interact. but by building layers of types and leveraging data-binding concepts, you write a lot less of it. the framework handles the transfers for you, in both Windows and Web applications.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.