Reposted the version on the Internet, and modified individual details (bugs) based on your own practices.
Using system;
Using system. Collections. Generic;
Using system. componentmodel;
Using system. drawing;
Using system. Data;
Using system. text;
Using system. Windows. forms;
Using system. collections;
Namespace UI. Common
{
Public partial class radiobuttonlist: usercontrol
{
# Region variable
Private object _ datasource;
Private buttonvaluemapping [] _ mappings;
Private object _ internaldatasource;
Private string _ displaymember;
Private string _ valuemember;
Private string _ value;
# Endregion
# Region ctor.
Public radiobuttonlist ()
{
Initializecomponent ();
}
# Endregion ctor
# Region prop
Public System. Object datasource
{
Get
{
Return _ datasource;
}
Set
{
_ Datasource = value;
}
}
Public String displaymember
{
Get
{
Return _ displaymember;
}
Set
{
_ Displaymember = value;
}
}
Public String valuemember
{
Get
{
Return _ valuemember;
}
Set
{
_ Valuemember = value;
}
}
Public String Value
{
Get
{
Return _ value;
}
Set
{
If (value! = NULL)
{
_ Value = value;
Setvalue (value );
}
}
}
# Endregion
# Region event
// Selectedindexchanged
Public Delegate void radioselectedhandler (Object sender, selectedeventargs E );
Public event radioselectedhandler radioitemseleted;
# Endregion
# Region Public Method
Public void databind ()
{
If (_ datasource = NULL)
Throw new nullreferenceexception ("null reference in property: datasource ");
Preparedata ();
Drawcontrol ();
}
# Endregion
// Internal function
# Region internal function
Void drawcontrol ()
{
Panel. Controls. Clear ();
Int COUNT = _ mappings. length;
// Draw and set Control
Int Height = 0;
Int x_aris = 10;
Int y_aris = 20;
For (INT I = 0; I <count; I ++)
{
// Create the radio button
Radiobutton radio = new radiobutton ();
Radio. Name = I. tostring ();
Radio. Text = _ mappings [I]. text;
Radio. autosize = true;
// Put radio button into the panel
Panel. Controls. Add (radio );
Radio. Location = new point (x_aris, y_aris + height );
Height + = radio. height;
// Add click event to radio button
Radio. Click + = new eventhandler (radio_click );
}
}
// Deal with the data source. Add additional code here if you want some new type of objet to be the datasource.
Void preparedata ()
{
If (_ datasource is datatable)
_ Internaldatasource = (datatable) _ datasource). defaultview;
If (_ datasource is dataview)
_ Internaldatasource = _ datasource;
// Exception
If (_ internaldatasource = NULL) throw new invalidcastexception ("the data source is not a desinged type .");
// Prepare the _ radiobutton & _ mappings to creat the radio Listre
# Region dataview & datatable as Data Source
If (_ internaldatasource is dataview)
{
Int radiocount = (dataview) _ internaldatasource). count;
_ Mappings = new buttonvaluemapping [radiocount];
Try
{
For (INT I = 0; I <radiocount; I ++)
{
// SET Index
_ Mappings [I]. Index = I;
// Set display text
_ Mappings [I]. Text = (dataview) _ internaldatasource) [I] [_ displaymember]. tostring ();
// Set Value
If (_ valuemember = NULL | _ valuemember = string. Empty)
{
_ Mappings [I]. value = I. tostring ();
}
Else
{
_ Mappings [I]. value = (dataview) _ internaldatasource) [I] [_ valuemember]. tostring ();
}
}
}
Catch (exception E)
{
Throw E;
}
}
# Endregion
}
// Internal event when a radio button is clicked. This fuction will call a public event.
Void radio_click (Object sender, eventargs E)
{
Value = _ mappings [Int. parse (radiobutton) sender). Name)]. value;
Selectedeventargs Se = new selectedeventargs ();
Se. value = _ mappings [Int. parse (radiobutton) sender). Name)]. value;
// After click, execute the selectedindexchanged. If the parent doesnot use this event, you should not write the underline
Radioitemseleted (this, SE );
}
// When value changes, set the relative radio button is selected.
Void setvalue (string value)
{
If (_ mappings = NULL)
Throw new nullreferenceexception ("data has not bound to the control ");
Foreach (buttonvaluemapping map in _ mappings)
{
If (Map. value = value)
{
(Radiobutton) panel. controls [map. Index. tostring ()]). Checked = true;
Return;
}
}
}
# Endregion
Internal struct buttonvaluemapping
{
Public int index;
Public string value;
Public String text;
}
/// <Summary>
/// Self defined class use for storaging the selected value, also can use as a parameter type
/// </Summary>
Public class selectedeventargs: eventargs
{
Public string value;
}
Private void initializecomponent ()
{
This. Panel = new system. Windows. Forms. Panel ();
This. suspendlayout ();
// Radiobuttonlist
This. Name = "radiobuttonlist ";
This. size = new system. Drawing. Size (490,220 );
This. resumelayout (false );
This. autoscroll = true;
// Panel
This. Panel. Location = new system. Drawing. Point (0, 3 );
This. Panel. Name = "Panel ";
This. Panel. size = new system. Drawing. Size (this. Width, this. Height );
This. Panel. tabindex = 0;
This. Panel. autoscroll = true;
This. Controls. Add (this. Panel );
}
}
}