Thursday, June 8, 2006

How To Cook Valerian Root

list view with databinding

With the new BindingSource component is relatively easy to create a list view with data binding support. First we create a control that inherits from ListView.
    public partial class    ListViewEx: ListView {

BindingSource BindingSource;
public ListViewEx () {

BindingSource source = new BindingSource ();
this View = View.Details;..
this FullRowSelect true = ;.
this gridlines = true ;
bindingSource.ListChanged + = OnListChanged;
}}

Next, the features implemented DataSource and DataMember. The attribute [attribute provider (typeof (IListSource))] provides that in the PropertyGrid
a Data Source window appears.

 [attribute provider (typeof   (IListSource))] public 
DataSource object
{
get {return bindingSource.DataSource;}
set bindingSource.DataSource = { value;}}


[Editor ( "System.Windows.Forms.Design.DataMemberListEditor,
system. string design, Version = 2.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a
"
, typeof (UITypeEditor))] public
DataMember

{get { bindingSource.DataMember return;}
set bindingSource.DataMember = { value;}}

implement Next we list changed event. In this we can fill the list view again, once the internal list of the BindingSource component changes.

  void  OnListChanged ( object  sender, ListChangedEventArgs e) 
{
this SetColumnHeaders ();.
this setValue ().
}

Next, we create the columns based on the type information. We get the first Item from the list and read from its properties. If a property is an IList is implemented, it be a parent-child relationship, we'll show it with Deshlab not. If there is a string, we create the column itself, otherwise the property Length as a column heading will be displayed. Otherwise, we simply assign the name to display the respective property. In my own classes, the display name be set by the respective property zuweißt the displayName attribute.

  private void    SetColumnHeaders () {

if (> bindingSource.List.Count 0) {

this Columns.Clear ();.
object DataItem = BindingSource.List [0];
foreach (PropertyDescriptor prop in
TypeDescriptor.GetProperties (DataItem)) {

if (prop.PropertyType.GetInterface ( "IList" ) ==
null) {

if (prop.ComponentType == typeof (string ))
this . Columns . Add ( "Value" );
else
this Columns.Add (prop.DisplayName).
}}

}}

Finally, we fill the list view with the values. For this, we iterate on the internal list of the BindingSource component. We now consider whether it is a string or a value type. With TypeDescriptor.GetProperties (DataItem). Count == 0, I make sure that a structure is behnadelt with their properties in the else branch. .
  private    void setValue () {

this Items.Clear ();
foreach (object DataItem BindingSource.List in ) {

if (DataItem is string )
this Items.Add ((string ) DataItem).
else if
(TypeDescriptor.GetProperties (DataItem) Count == 0.

&& dataItem is System.ValueType)
{
if ( this .Columns.Count == 0)
this .Columns.Add( "Value" );
this .Items.Add(dataItem.ToString());
}
else
{
PropertyDescriptorCollection props =

TypeDescriptor.GetProperties(dataItem);
List< string > valueList = new List< string >();
foreach (PropertyDescriptor propDesc in props)
{
string value =
propDesc.GetValue(dataItem) == null ?
string .Empty :
propDesc.GetValue(dataItem).ToString();
valueList.Add(value);
}
this .Items.Add
( new ListViewItem(valueList.ToArray()));
}
}
}

0 comments:

Post a Comment