目的:项目有需要,创建一个支持数据绑定的单选按钮列表。
设想:动态识别多种数据源, 动态生成一定数量的按钮。
准备:创建一个自定义控件,添加一个Panel对象。
优点: 支持多种数据源做绑定,并可以自己添加自定义数据源。
缺点:错误的抛出没有做到位,没有完全做到设计时定义所有数据。原因:懒。
usingSystem;
usingSystem.Collections.Generic;
ponentModel;
usingSystem.Drawing;
usingSystem.Data;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Collections;
namespaceRVProject
{
publicpartialclassRadioButtonList:UserControl
{
Variable#regionVariable
privateObject_dataSource;
privateButtonValueMapping[]_mappings;
privateObject_internalDataSource;
privatestring_displayMember;
privatestring_valueMember;
privatestring_value;
#endregion
ctor.#regionctor.
publicRadioButtonList()
{
InitializeComponent();
}
#endregion
prop#regionprop
publicSystem.ObjectDataSource
{
get
{
return_dataSource;
}
set
{
_dataSource=value;
}
}
publicstringDisplayMember
{
get
{
return_displayMember;
}
set
{
_displayMember=value;
}
}
publicstringValueMember
{
get
{
return_valueMember;
}
set
{
_valueMember=value;
}
}
publicstringValue
{
get
{
return_value;
}
set
{
if(Value!=null)
{
_value=value;
SetValue(value);
}
}
}
#endregion
event#regionevent
publicdelegatevoidRadioSelectedHandler(objectsender,SelectedEventArgse);
publiceventRadioSelectedHandlerRadioItemSeleted;
#endregion
publicmethod#regionpublicmethod
publicvoidDataBind()
{
if(_dataSource==null)
thrownewNullReferenceException("NullreferenceinProperty:DataSource");
PrepareData();
DrawControl();
}
#endregion
//InternalFunction
internalfunction#regioninternalfunction
voidDrawControl()
{
panel.Controls.Clear();
intcount=_mappings.Length;
//Drawandsetcontrol
intheight=0;
intx_aris=10;
inty_aris=10;
for(inti=0;i<count;i++)
{
//createtheradiobutton
RadioButtonradio=newRadioButton();
radio.Name=i.ToString();
radio.Text=_mappings[i].Text;
radio.AutoSize=true;
//putradiobuttonintothepanel
panel.Controls.Add(radio);
radio.Location=newPoint(x_aris,y_aris+height);
height+=radio.Height;
//Addclickeventtoradiobutton
radio.Click+=newEventHandler(radio_Click);
}
}
//Dealwiththedatasource.Addadditionalcodehereifyouwantsomenewtypeofobjettobethedatasource.
voidPrepareData()
{
//dealwiththedatasouce
if(_dataSourceisDataTable)
_internalDataSource=((DataTable)_dataSource).DefaultView;
if(_dataSourceisDataView)
_internalDataSource=_dataSource;
//Exception
if(_internalDataSource==null)thrownewInvalidCastException("Thedatasourceisnotadesingedtype.");
//preparethe_radiobutton&_mappingstocreattheradiolistre
DataView&DataTableasdatasource#regionDataView&DataTableasdatasource
if(_internalDataSourceisDataView)
{
intradioCount=((DataView)_internalDataSource).Count;
_mappings=newButtonValueMapping[radioCount];
try
{
for(inti=0;i<radioCount;i++)
{
//Setindex
_mappings[i].Index=i;
//Setdisplaytext
_mappings[i].Text=((DataView)_internalDataSource)[i][_displayMember].ToString();
//Setvalue
if(_valueMember==null||_valueMember==string.Empty)
{
_mappings[i].Value=i.ToString();
}
else
{
_mappings[i].Value=((DataView)_internalDataSource)[i][_valueMember].ToString();
}
}
}
catch(Exceptione)
{
throwe;
}
}
#endregion
}
//internaleventwhenaradiobuttonisclicked.thisfuctionwillcallapublicevent.
voidradio_Click(objectsender,EventArgse)
{
_value=_mappings[int.Parse(((RadioButton)sender).Name)].Value;
SelectedEventArgsse=newSelectedEventArgs();
se.Value=_mappings[int.Parse(((RadioButton)sender).Name)].Value;
RadioItemSeleted(this,se);
}
//WhenValuechanges,therelativeradiobuttonisselected.
voidSetValue(stringvalue)
{
if(_mappings==null)
thrownewNullReferenceException("Datahasnotboundtothecontrol");
foreach(ButtonValueMappingmapin_mappings)
{
if(map.Value==value)
{
((RadioButton)panel.Controls[map.Index.ToString()]).Checked=true;
}
}
}
#endregion
internalstructButtonValueMapping
{
publicintIndex;
publicstringValue;
publicstringText;
}
publicclassSelectedEventArgs:EventArgs
{
publicstringValue;
}
}
}