Propertygrig again and combobox

J

J-L

Hi from France,

I use propertygrid with Visual C# 2008 Express.

I know how to display a values list in a combobox using an enum.

I need today to display a combobox but with personalized content.

I select an employee object in my propertygrid. This employee need to
obtain a profile object (rights user). The profiles list are read from
database table in a List.

Is it possible to fill and use a such combobox in propertygrid ?

J-L
 
M

Marc Gravell

Sure; just set the DataSource, DisplayMember and ValueMember of a
DataGridViewComboBoxColumn (below [using C# 3 for brevity]).

Marc

using System.Collections.Generic;
using System.Windows.Forms;
using System.ComponentModel;
using System;

class Role
{
public string Name { get; set; }
public string Description { get; set; }
}
class User
{
public string Name { get; set; }
public string Role { get; set; }
}
static class Program
{
[STAThread]
static void Main()
{
List<Role> roles = new List<Role>
{
new Role {Name="ADMIN", Description="Administrator"},
new Role {Name="GUEST", Description="Guest"},
new Role {Name="USER", Description="Standard User"}
};
BindingList<User> users = new BindingList<User>
{
new User {Name = "Fred", Role="ADMIN"},
new User {Name="Jo", Role="GUEST"}
};
Application.Run(new Form
{
Text = "DataGridView Demo",
Controls =
{
new DataGridView {
Dock = DockStyle.Fill,
AutoGenerateColumns = false,
Columns = {
new DataGridViewTextBoxColumn {
DataPropertyName = "Name",
HeaderText = "Name"
}, new DataGridViewComboBoxColumn {
DataPropertyName = "Role",
DataSource = roles,
DisplayMember = "Description",
ValueMember = "Name"
}
},
DataSource = users
}
}
});

}
}
 
D

Dobedani

Hi Marc and others,

Thanks for your example. I often work with lists - mostly List<String>
or a C# implmentation of TStringList from CodeGear ;-) If I want to
add the items to a ComboBox or similar Control, I approach the Items
collection thereof. My colleagues do the same. Yesterday somebody told
me that this is the way things were done in the Stone Age. He instead
assigned a locally defined list to the DataSource of the ComboBox to
be populated. It was not even a list, but an array of strings:
String[] names; and ok, it worked ...

However, things did not work as I expected. This morning I promoted
the list to a private field and changed the type to List<String>; i.e.
I made the list visible within the whole class. I then added a method
to modify this list. I was then expecting that the ComboBox would be
updated when the list would change. Not so. I tried all sorts of
things - incl. wrapping the strings and assigning DisplayMember and
ValueMember of the ComboBox - but to no avail.
Unfortunately, I was not told that I should use BindingList! Now I
understand things better. I am adding the following example for
whoever may have the same problems. Start a new project and add the
code to class Form1.cs with a combobox named matrixComboBox and a
button named btnRemove.

One question: why does the DataSourceChanged event not fire when I
remove an Item?

Kind regards,
Dobedani

namespace DataSrcTest {
public partial class Form1 : Form {
private BindingList<String> matrixNames;

public Form1() {
InitializeComponent();
PopulateList();
}

private void PopulateList() {
matrixNames = new BindingList<String>();
String[] names = { "Matt", "Luke", "Marc", "John", "Paul",
"Pete", "Jude" };
foreach (String s in names) {
matrixNames.Add(s);
}
matrixComboBox.DataSource = matrixNames;
}

private void btnRemove_Click(object sender, EventArgs e) {

String selectedWS =
matrixComboBox.SelectedItem.ToString();
if (matrixNames.Contains(selectedWS)) {
matrixNames.Remove(selectedWS);
}
if (matrixNames.Count == 0) {
MessageBox.Show("I hope you read the New Testament!");
}
}
}
}
 
M

Marc Gravell

Works fine for me...

static class Program
{
[STAThread]
static void Main()
{
string[] names= {"Matt", "Luke", "Marc",
"John", "Paul", "Pete", "Jude"};
BindingList<string> list = new BindingList<string>();
foreach (string name in names)
{
list.Add(name);
}
ComboBox cb = new ComboBox { DataSource = list, Dock =
DockStyle.Top };
cb.DropDownStyle = ComboBoxStyle.DropDownList;
Button btn = new Button { Dock = DockStyle.Bottom, Text
= "Remove" };
btn.Click += delegate
{
list.Remove((string)cb.SelectedItem);
};
Application.EnableVisualStyles();
Application.Run(new Form { Controls = { cb, btn } });
}
}
 
M

Marc Gravell

I've tried with your code, and the drop-down definitely changes to match
the data.

For info, DataSourceChanged isn't firing because we aren't actually
changing the DataSource property - rather something inside the
data-source is changing. If you want to watch those changes, use a
BindingSource as an intermediary:

BindingSource bs = new BindingSource();
bs.DataSource = matrixNames;
bs.ListChanged += delegate(object sender,
ListChangedEventArgs args)
{
this.Text = string.Format("{0}: {1}",
args.NewIndex, args.ListChangedType);
};
matrixComboBox.DataSource = bs;

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top