views:

763

answers:

3

Say I have an business object called Sample and I have BindingList of Samples. A sample has 4 properties.

Can I select which properties are bound to DataGrid or there no option to customize such a thing?

NOTE: I am using Compact Framework, where is NO DataGridView, as well as Autogenerate property and DataMember property.

Please keep this in mind while replying.

A: 

I'm assuming you mean DataGrid in WinForms, but the same is applicable to most bindable controls.

Yes you can do this. The way to do this is a 2 step process

  • Set the DataSource member to be the instance of the BindingList<T>.
  • Set the DataMember property to be the string name of the property you want bound.
JaredPar
Thanks. DataMember property is missing from Compact Framework DataGrid class. Is there a way to do it on the BindingList level? WHat I am looking for is a way to mark a Sample property not bindable....
gnomixa
A: 
BindingList<Sample> samples = new BindingList<Sample>();
DataGridView dgv = new DataGridView();
dgv.DataSource = samples;

This should display each public property as a column on the DataGridView. If you want to change which properties are displayed, you need to do the following as well:

dgv.AutoGenerateColumns = false;

and go into the properties of the datagridview, add the columns manually and set the DataPropertyName to the property name.

If you created the datagridview in code, the following will create and add a column to the dgv.

DataGridViewColumn dgvc = new DataGridViewColumn();
dgvc.Name = "PropertyA";
dgvc.HeaderText = "Property A";
dgvc.DataPropertyName = "PropertyA";
dgv.Columns.Add(dgvc);


EDIT

This SHOULD give you something closer to what you were wanting. However, because it uses an anonymous class, you can't use BindingList (that I know of). Alternativly, you can create a SampleBinding class that just has the properties you want to be displayed and generate those from the list of normal samples.

public class Sample
{
    public int PropertyA {get;set;}
    public bool PropertyB {get;set;}
    public string PropertyC {get;set;}
    public double PropertyD {get;set;}
}

List<Sample> samples = new List<Samples>(GetSamples());
var sampleBinding = from sample in samples
                    select new
                    {
                        PropertyA = sample.PropertyA,
                        PropertyC = sample.PropertyC
                    };

BindingList bl = new BindingList();
bl.DataSource = sampleBinding;
dgv.DataSource = bl;


EDIT 2

public class Sample
{
    [Browsable(false)]
    public int PropertyA {get;set;}
    public bool PropertyB {get;set;}
    public string PropertyC {get;set;}
    [Browsable(false)]
    public double PropertyD {get;set;}
}
Justin Drury
Thanks, I am doing something equivalent to this in Compact Framework. But this is not very dynamic as I still need to either hardcode "PropertyA" string or load it to some constant. I was more refering to perhaps each property of Sample having a property Bindable which could be turned on or off. Or in other words, binding the BindingList customized....I guess it's not possible? Let's forget about dataGrid Columns for now (I know how to do THAT). Is there a way to do through BindingList?
gnomixa
Looking at the properties/methods for BindingList<T> that doesn't seem likely. Give me a few minutes to whip up some more code for another way you might try this.
Justin Drury
something like thishttp://www.jardinesoftware.net/2007/10/23/hide-properties-in-bindinglist/but he/she doesn't elaborate and don't quite get how what he wrote is used.
gnomixa
Ahhh, I just read your comment after submitting my code... just add [Browsable(false)] to the properties you don't want displayed in the DataGridView.
Justin Drury
See my EDIT 2 for how to do what was listed in the link you provided.
Justin Drury
Browsable attribute of course is not included in Compact Framework, so ignore my above note.
gnomixa
what would have been so easy in full blown .net is going to be a pain and lot of hard coding in compact framework. god i hate this platform.rant over.
gnomixa
Hehe, I can feel the pain :/
Justin Drury
i will use the grid columns way (as I am doing it now). seems like that's the only way to go. Thanks
gnomixa
No problem. Good luck with your project.
Justin Drury
i have actually decided not to use BindingList but stay with the DataTable as own objective with the BindingList was not achieved. DataTable gives me more column flexibility than BindingList where the business object needs to be rigidly defined. Since I can't hide/show columns with ease I might as well not use this method. It makes more sense to use it in full blown .net I think.
gnomixa
Thanks Justin! Thank you for your help also.
gnomixa
A: 

I have handled this a few different ways, hopefully this is helpful.

The first option, as Justin mentioned, is to set AutoGennerateColumns = false, and do it manually from there. If you bind it, the runtime will create columns for all of the public properties of Sample. If you want to remove them, you can do that with

DataGridView.Columns["SomePropertyOfSample"].Remove();

This solution is a bit problematic, as you need to keep it updated, and explicitly remove items.

Justin's Edit 2 option of setting the Browsable attribute to false on the property is interesting, I have not tried that before.

The solution that I have ended up using, and that I think works pretty well revolves around an interface.

I had two different DataGridViews that needed to show the same data, but showing and hiding different colums each time. In this case you would do:

public interface ISimpleSample
{
  string Name {get;}
  int ID {get;}
}

public interface IAdvancedSample
{
  string Name {get; set;}
  int ID {get; set;}
  string Make {get; set;}
  string Model {get; set;}
}

public class Sample : ISimpleSample, IAdvancedSample
{
  //Implementation skipped
}

You then create your Sample collection using

BindingList<ISimpleSample> = new BindingList<ISimpleSample>();

and bind to that.

If you want to add columns later, you just add them to the appropriate interface.

This worked well for my project, let me know what you think.

Brandon