views:

884

answers:

2

I'm trying to use a System.Windows.Forms.DataGrid control in my Compact Framework 3.5 Window Mobile Professional 6 SDK based project to show some properties of objects of type Something by binding the DataGrid to a List<SomethingWrapper> instance like this:

public class SomethingWrapper {
   private Something data;
   public SomethingWrapper(Something data) { this.data = data; }
   public string Column1 { get { /* string from this.data */ } }
   public string Column2 { get { /* string from this.data */ } }
}

public class SomethingList : List<SomethingWrapper> {
   public SomethingList(IEnumerable<Something> items) {
      foreach (var item in items) Add(new SomethingWrapper(item));
      Sort((a, b) => a.Column2.CompareTo(b.Column2);
   }
}

/* ... */

IEnumerable<Something> dataToShow = /* assume this is filled correctly */
SomethingDataGrid.DataSource = new SomethingList(dataToShow);

This seems to work fine: the correct data is shown in the grid with two columns called Column1 and Column2 and sorted on the second column. I want this to be a readonly view of this data, so all is fine.

However, I would like to set column widths and cannot seem to get this to work...

Have tried to obvious: creating TableStyle, creating textbox column style instance per column, adding it to the TableStyle and setting SomethingDataGrid.TableStyle to resulting table style. (This is from memory, or I would also show the exact code I'm using. If needed, I can add that to the question somewhere later today.)

Nothing changes however. I suspect this has something to do with the MappingName on the TableStyle object; all examples I could find yesterday evening seem to be for databinding a DataSet to the DataGrid and setting MappingName to the correct table name in the DataSet. Otherwise, the table style will not do what you expect, which is the behavior I'm seeing.

Question: am I looking in the correct place for a solution to my problem, and if so, what do I need to set TableStyle.MappingName to when binding to a List<T> to show properties of T...?

(Tried to check for possible duplicates, but was unable to find exact matches. Please correct me if I turn out to be wrong there.)

A: 

Ah, didn't look well enough after all: duplicate question found. Will try deriving from BindingList<T> and/or using a binding source so I can start calling BindingSource.GetListName(null) to get a MappingName. Hope this will help. If not, I'll be back...

peSHIr
Using a TableStyle.MappingName = BindingSource.GetListName(null) proved to work fine.
peSHIr
+1  A: 

You can do this by creating a DataGridTableStyle

Here is an extension method that I use:

public static void SetColumnStyles<T>(this DataGrid ctrl, T data, params ColumnStyle[] column) where T: class 
    {
        var ts = new DataGridTableStyle();
        ts.MappingName = data.GetType().Name;

        foreach (var style in column)
        {
            ts.GridColumnStyles.AddColumn(style.Header, style.Column, style.Width);
        }

        ctrl.TableStyles.Clear();
        ctrl.TableStyles.Add(ts);
    }

Then I call it like this:

    var newList = queriableData.ToList();
    ProductEdit.DataSource = newList;
    ProductEdit.SetColumnStyles(newList, new[]
                                      {
                                          new ColumnStyle("Name", 200),
                                          new ColumnStyle("Manufacturer", 100),
                                          new ColumnStyle("Size", 20)
                                      });

where newList is a generic list of objects.

Chris Brandsma
I was doing this, but the actual question was more along the lines of "What do I set ts.MappingName to when I bind to something else than a DataSet?". Glad to hear from you that apparently I can just use the type name of the data source. Thanks. Now I can chuck that BindingSource control again. Don't really need to see my columns in the designer. ;-)
peSHIr
Oh, you need the .ToList() before you bound. Sorry man, I missed that. I hope the rest of the code is useful for you.
Chris Brandsma
Just tried the MappingName = GetType().Name thing, but that did not seem to work. Expected it to, as I found in the MSDN description of ListBindingHelper.GetListName() that it returns the type name of the data when listAccessors is set to null, which would amount to GetType().Name anyway. Stumped for now. Might look into it later. Using a BindingSource and BindingSource.GetListName(null) as TableName seems to continue to work though. So that's fine for now.
peSHIr
+1 for ts.MappingName = data.GetType().Name. I was upgrading some .NET 1.1 code to .NET 3.5 and noticed the grid no longer worked (in .NET 1.1 it was binding to an ArrayList, it now binds to a List<T>). A bit of Googling and I found your answer for MappingName.
RichardOD