Updating the form's fields

V

Vanessa

Hi All!

I am with a situation where I am not getting the right updating to the
form's fields. The situation is the following one:

I have one combobox and one textbox. I am using the CurrentChanged event of
the BindingSource of the combobox to update the textbox. When selecting an
item in the combobox or when selecting a row in the grid, it is updating the
textbox correctly. The problem is when I apply a filter in the grid, and then
the grid has no rows. I already made the following attempts:

- When there is no row in the grid, the event is not called, and textbox
mantains the previous content;
- If I call the CurrentChanged event directly when there is no rows in the
grid, in this case I clean up the textbox, but when I apply a filter again in
the grid and the position of the combobox does not modify (that is, it is in
the same register), the CurrentChanged is not called, and edit is blank
(because I cleaned before);
- I already tried to use “combo.SelectedIndex = -1†but also did not worked.

Does someone has any idea of how can I solve this situation?

Thank you for any suggestion!
Vanessa
 
M

Morten Wennevik [C# MVP]

Hi Vanessa,

I suspect you get some invalid data breaking the databinding. Try handling
the DataError event of the BindingSource.

It is a bit unclear what you have databound and not, and in fact what
controls you have. What is the relationship between the (data)grid and the
combobox? Are you databinding a ComboBox to one BindingSource and a DataGrid
to another, while the TextBox remains unbound and is updated manually when a
change occurs in either the ComboBox or the DataGrid?

Other things to try. Bind the TextBox to the same BindingSource as the
ComboBox rather than updating it in the CurrentChanged event (although this
won't work if you use the same TextBox to display values from another
BindingSource as well). Try handling the ListChanged event, which should
fire if the underlying datasource changes. If the list is changed, get the
BindingSource.Current value and update the TextBox accordingly.
 
V

Vanessa

Hi Morten!

Let me explain better what I want to do.

My database has the following tables:

Table A - the main table that is shown in the form. It has a field that is a
key into Table B;
Table B - it is related to Table A and it is a combobox in the form. It has
a field that is a key into Table C;
Table C - it is related to Table B and it has a description field to show in
a textbox.

So, my question is, how can I make the binding to the textbox that is on
Table C? What I want is to show the description field from Table C, whose key
is on the Table B (combobox).

Thank you,
Vanessa

Morten Wennevik said:
Hi Vanessa,

I suspect you get some invalid data breaking the databinding. Try handling
the DataError event of the BindingSource.

It is a bit unclear what you have databound and not, and in fact what
controls you have. What is the relationship between the (data)grid and the
combobox? Are you databinding a ComboBox to one BindingSource and a DataGrid
to another, while the TextBox remains unbound and is updated manually when a
change occurs in either the ComboBox or the DataGrid?

Other things to try. Bind the TextBox to the same BindingSource as the
ComboBox rather than updating it in the CurrentChanged event (although this
won't work if you use the same TextBox to display values from another
BindingSource as well). Try handling the ListChanged event, which should
fire if the underlying datasource changes. If the list is changed, get the
BindingSource.Current value and update the TextBox accordingly.



--
Happy Coding!
Morten Wennevik [C# MVP]


Vanessa said:
Hi All!

I am with a situation where I am not getting the right updating to the
form's fields. The situation is the following one:

I have one combobox and one textbox. I am using the CurrentChanged event of
the BindingSource of the combobox to update the textbox. When selecting an
item in the combobox or when selecting a row in the grid, it is updating the
textbox correctly. The problem is when I apply a filter in the grid, and then
the grid has no rows. I already made the following attempts:

- When there is no row in the grid, the event is not called, and textbox
mantains the previous content;
- If I call the CurrentChanged event directly when there is no rows in the
grid, in this case I clean up the textbox, but when I apply a filter again in
the grid and the position of the combobox does not modify (that is, it is in
the same register), the CurrentChanged is not called, and edit is blank
(because I cleaned before);
- I already tried to use “combo.SelectedIndex = -1†but also did not worked.

Does someone has any idea of how can I solve this situation?

Thank you for any suggestion!
Vanessa
 
M

Morten Wennevik [C# MVP]

Hi Vanessa,

I've attached some code demonstrating how you can do this using business
objects. You should be able to do it with relational tables as well, but I'm
not so familiar using tables as datasource. The code assumes you have a
DataGridView, ComboBox and TextBox on your Form


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

ClassA a = new ClassA("A");
BindingSource sourceA = new BindingSource(a, "");
BindingSource sourceB = new BindingSource(sourceA, "BList");
BindingSource sourceC = new BindingSource(sourceB, "CList");
dataGridView1.DataSource = sourceB;
comboBox1.DataSource = sourceC;
comboBox1.DisplayMember = "Name";
textBox1.DataBindings.Add("Text", sourceC, "Id");
}
}

public class ClassA
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassB> _bList;

public BindingList<ClassB> BList
{
get { return _bList; }
set { _bList = value; }
}
public ClassA(string name)
{
Name = name;
BList = new BindingList<ClassB>();

BList.Add(new ClassB(Name + " B 1"));
BList.Add(new ClassB(Name + " B 2"));
}
}

public class ClassB
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassC> _cList;

public BindingList<ClassC> CList
{
get { return _cList; }
set { _cList = value; }
}
public ClassB(string name)
{
Name = name;
CList = new BindingList<ClassC>();

CList.Add(new ClassC(Name + " C 1"));
CList.Add(new ClassC(Name + " C 2"));
}
}

public class ClassC
{
static int count = 0;
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private int _id;

public int Id
{
get { return _id; }
set { _id = value; }
}
public ClassC(string name)
{
Name = name;
Id = count++;
}
}


--
Happy Coding!
Morten Wennevik [C# MVP]


Vanessa said:
Hi Morten!

Let me explain better what I want to do.

My database has the following tables:

Table A - the main table that is shown in the form. It has a field that is a
key into Table B;
Table B - it is related to Table A and it is a combobox in the form. It has
a field that is a key into Table C;
Table C - it is related to Table B and it has a description field to show in
a textbox.

So, my question is, how can I make the binding to the textbox that is on
Table C? What I want is to show the description field from Table C, whose key
is on the Table B (combobox).

Thank you,
Vanessa

Morten Wennevik said:
Hi Vanessa,

I suspect you get some invalid data breaking the databinding. Try handling
the DataError event of the BindingSource.

It is a bit unclear what you have databound and not, and in fact what
controls you have. What is the relationship between the (data)grid and the
combobox? Are you databinding a ComboBox to one BindingSource and a DataGrid
to another, while the TextBox remains unbound and is updated manually when a
change occurs in either the ComboBox or the DataGrid?

Other things to try. Bind the TextBox to the same BindingSource as the
ComboBox rather than updating it in the CurrentChanged event (although this
won't work if you use the same TextBox to display values from another
BindingSource as well). Try handling the ListChanged event, which should
fire if the underlying datasource changes. If the list is changed, get the
BindingSource.Current value and update the TextBox accordingly.



--
Happy Coding!
Morten Wennevik [C# MVP]


Vanessa said:
Hi All!

I am with a situation where I am not getting the right updating to the
form's fields. The situation is the following one:

I have one combobox and one textbox. I am using the CurrentChanged event of
the BindingSource of the combobox to update the textbox. When selecting an
item in the combobox or when selecting a row in the grid, it is updating the
textbox correctly. The problem is when I apply a filter in the grid, and then
the grid has no rows. I already made the following attempts:

- When there is no row in the grid, the event is not called, and textbox
mantains the previous content;
- If I call the CurrentChanged event directly when there is no rows in the
grid, in this case I clean up the textbox, but when I apply a filter again in
the grid and the position of the combobox does not modify (that is, it is in
the same register), the CurrentChanged is not called, and edit is blank
(because I cleaned before);
- I already tried to use “combo.SelectedIndex = -1†but also did not worked.

Does someone has any idea of how can I solve this situation?

Thank you for any suggestion!
Vanessa
 
V

Vanessa

Hi Morten!

Thank you for the example. It is almost what I want, but image that I put a
filter in the datagridview, just to show all names starting with "B" (in the
example all names start with "A"). In this case there will not have rows on
the grid, and the combo and textbox would be empty. How can I "clean" these
controls?

Thank you,
Vanessa


Morten Wennevik said:
Hi Vanessa,

I've attached some code demonstrating how you can do this using business
objects. You should be able to do it with relational tables as well, but I'm
not so familiar using tables as datasource. The code assumes you have a
DataGridView, ComboBox and TextBox on your Form


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

ClassA a = new ClassA("A");
BindingSource sourceA = new BindingSource(a, "");
BindingSource sourceB = new BindingSource(sourceA, "BList");
BindingSource sourceC = new BindingSource(sourceB, "CList");
dataGridView1.DataSource = sourceB;
comboBox1.DataSource = sourceC;
comboBox1.DisplayMember = "Name";
textBox1.DataBindings.Add("Text", sourceC, "Id");
}
}

public class ClassA
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassB> _bList;

public BindingList<ClassB> BList
{
get { return _bList; }
set { _bList = value; }
}
public ClassA(string name)
{
Name = name;
BList = new BindingList<ClassB>();

BList.Add(new ClassB(Name + " B 1"));
BList.Add(new ClassB(Name + " B 2"));
}
}

public class ClassB
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassC> _cList;

public BindingList<ClassC> CList
{
get { return _cList; }
set { _cList = value; }
}
public ClassB(string name)
{
Name = name;
CList = new BindingList<ClassC>();

CList.Add(new ClassC(Name + " C 1"));
CList.Add(new ClassC(Name + " C 2"));
}
}

public class ClassC
{
static int count = 0;
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private int _id;

public int Id
{
get { return _id; }
set { _id = value; }
}
public ClassC(string name)
{
Name = name;
Id = count++;
}
}


--
Happy Coding!
Morten Wennevik [C# MVP]


Vanessa said:
Hi Morten!

Let me explain better what I want to do.

My database has the following tables:

Table A - the main table that is shown in the form. It has a field that is a
key into Table B;
Table B - it is related to Table A and it is a combobox in the form. It has
a field that is a key into Table C;
Table C - it is related to Table B and it has a description field to show in
a textbox.

So, my question is, how can I make the binding to the textbox that is on
Table C? What I want is to show the description field from Table C, whose key
is on the Table B (combobox).

Thank you,
Vanessa

Morten Wennevik said:
Hi Vanessa,

I suspect you get some invalid data breaking the databinding. Try handling
the DataError event of the BindingSource.

It is a bit unclear what you have databound and not, and in fact what
controls you have. What is the relationship between the (data)grid and the
combobox? Are you databinding a ComboBox to one BindingSource and a DataGrid
to another, while the TextBox remains unbound and is updated manually when a
change occurs in either the ComboBox or the DataGrid?

Other things to try. Bind the TextBox to the same BindingSource as the
ComboBox rather than updating it in the CurrentChanged event (although this
won't work if you use the same TextBox to display values from another
BindingSource as well). Try handling the ListChanged event, which should
fire if the underlying datasource changes. If the list is changed, get the
BindingSource.Current value and update the TextBox accordingly.



--
Happy Coding!
Morten Wennevik [C# MVP]


:

Hi All!

I am with a situation where I am not getting the right updating to the
form's fields. The situation is the following one:

I have one combobox and one textbox. I am using the CurrentChanged event of
the BindingSource of the combobox to update the textbox. When selecting an
item in the combobox or when selecting a row in the grid, it is updating the
textbox correctly. The problem is when I apply a filter in the grid, and then
the grid has no rows. I already made the following attempts:

- When there is no row in the grid, the event is not called, and textbox
mantains the previous content;
- If I call the CurrentChanged event directly when there is no rows in the
grid, in this case I clean up the textbox, but when I apply a filter again in
the grid and the position of the combobox does not modify (that is, it is in
the same register), the CurrentChanged is not called, and edit is blank
(because I cleaned before);
- I already tried to use “combo.SelectedIndex = -1†but also did not worked.

Does someone has any idea of how can I solve this situation?

Thank you for any suggestion!
Vanessa
 
M

Morten Wennevik [C# MVP]

Hi Vanessa,

I'm not sure how a DataView/Filter would work with this, but if a parent
bindingsource has no objects, the child bindingsources should clear any bound
controls as well.

If you add two buttons, move the ClassA reference to a global scope, and add
the following code to the example, clicking one button will simulate
filtering by removing all objects and the second one will add new objects.
In real life, ClassA would expose a filter property. If no items are shown
in the grid, the combobox and textbox will clear as well.

ClassA a = new ClassA("A");
private void button1_Click(object sender, EventArgs e)
{
a.BList.Clear();
return;
}

private void button2_Click(object sender, EventArgs e)
{
a.BList.Add(new ClassB("T1"));
a.BList.Add(new ClassB("T2"));
a.BList.Add(new ClassB("T3"));
return;
}

I'm afraid I can't help you on how to apply this to filtering and DataView

--
Happy Coding!
Morten Wennevik [C# MVP]


Vanessa said:
Hi Morten!

Thank you for the example. It is almost what I want, but image that I put a
filter in the datagridview, just to show all names starting with "B" (in the
example all names start with "A"). In this case there will not have rows on
the grid, and the combo and textbox would be empty. How can I "clean" these
controls?

Thank you,
Vanessa


Morten Wennevik said:
Hi Vanessa,

I've attached some code demonstrating how you can do this using business
objects. You should be able to do it with relational tables as well, but I'm
not so familiar using tables as datasource. The code assumes you have a
DataGridView, ComboBox and TextBox on your Form


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

ClassA a = new ClassA("A");
BindingSource sourceA = new BindingSource(a, "");
BindingSource sourceB = new BindingSource(sourceA, "BList");
BindingSource sourceC = new BindingSource(sourceB, "CList");
dataGridView1.DataSource = sourceB;
comboBox1.DataSource = sourceC;
comboBox1.DisplayMember = "Name";
textBox1.DataBindings.Add("Text", sourceC, "Id");
}
}

public class ClassA
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassB> _bList;

public BindingList<ClassB> BList
{
get { return _bList; }
set { _bList = value; }
}
public ClassA(string name)
{
Name = name;
BList = new BindingList<ClassB>();

BList.Add(new ClassB(Name + " B 1"));
BList.Add(new ClassB(Name + " B 2"));
}
}

public class ClassB
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassC> _cList;

public BindingList<ClassC> CList
{
get { return _cList; }
set { _cList = value; }
}
public ClassB(string name)
{
Name = name;
CList = new BindingList<ClassC>();

CList.Add(new ClassC(Name + " C 1"));
CList.Add(new ClassC(Name + " C 2"));
}
}

public class ClassC
{
static int count = 0;
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private int _id;

public int Id
{
get { return _id; }
set { _id = value; }
}
public ClassC(string name)
{
Name = name;
Id = count++;
}
}


--
Happy Coding!
Morten Wennevik [C# MVP]


Vanessa said:
Hi Morten!

Let me explain better what I want to do.

My database has the following tables:

Table A - the main table that is shown in the form. It has a field that is a
key into Table B;
Table B - it is related to Table A and it is a combobox in the form. It has
a field that is a key into Table C;
Table C - it is related to Table B and it has a description field to show in
a textbox.

So, my question is, how can I make the binding to the textbox that is on
Table C? What I want is to show the description field from Table C, whose key
is on the Table B (combobox).

Thank you,
Vanessa

:

Hi Vanessa,

I suspect you get some invalid data breaking the databinding. Try handling
the DataError event of the BindingSource.

It is a bit unclear what you have databound and not, and in fact what
controls you have. What is the relationship between the (data)grid and the
combobox? Are you databinding a ComboBox to one BindingSource and a DataGrid
to another, while the TextBox remains unbound and is updated manually when a
change occurs in either the ComboBox or the DataGrid?

Other things to try. Bind the TextBox to the same BindingSource as the
ComboBox rather than updating it in the CurrentChanged event (although this
won't work if you use the same TextBox to display values from another
BindingSource as well). Try handling the ListChanged event, which should
fire if the underlying datasource changes. If the list is changed, get the
BindingSource.Current value and update the TextBox accordingly.



--
Happy Coding!
Morten Wennevik [C# MVP]


:

Hi All!

I am with a situation where I am not getting the right updating to the
form's fields. The situation is the following one:

I have one combobox and one textbox. I am using the CurrentChanged event of
the BindingSource of the combobox to update the textbox. When selecting an
item in the combobox or when selecting a row in the grid, it is updating the
textbox correctly. The problem is when I apply a filter in the grid, and then
the grid has no rows. I already made the following attempts:

- When there is no row in the grid, the event is not called, and textbox
mantains the previous content;
- If I call the CurrentChanged event directly when there is no rows in the
grid, in this case I clean up the textbox, but when I apply a filter again in
the grid and the position of the combobox does not modify (that is, it is in
the same register), the CurrentChanged is not called, and edit is blank
(because I cleaned before);
- I already tried to use “combo.SelectedIndex = -1†but also did not worked.

Does someone has any idea of how can I solve this situation?

Thank you for any suggestion!
Vanessa
 
V

Vanessa

Hi Morten!

It is working like I wanted.

Thank you very much!
Vanessa


Morten Wennevik said:
Hi Vanessa,

I'm not sure how a DataView/Filter would work with this, but if a parent
bindingsource has no objects, the child bindingsources should clear any bound
controls as well.

If you add two buttons, move the ClassA reference to a global scope, and add
the following code to the example, clicking one button will simulate
filtering by removing all objects and the second one will add new objects.
In real life, ClassA would expose a filter property. If no items are shown
in the grid, the combobox and textbox will clear as well.

ClassA a = new ClassA("A");
private void button1_Click(object sender, EventArgs e)
{
a.BList.Clear();
return;
}

private void button2_Click(object sender, EventArgs e)
{
a.BList.Add(new ClassB("T1"));
a.BList.Add(new ClassB("T2"));
a.BList.Add(new ClassB("T3"));
return;
}

I'm afraid I can't help you on how to apply this to filtering and DataView

--
Happy Coding!
Morten Wennevik [C# MVP]


Vanessa said:
Hi Morten!

Thank you for the example. It is almost what I want, but image that I put a
filter in the datagridview, just to show all names starting with "B" (in the
example all names start with "A"). In this case there will not have rows on
the grid, and the combo and textbox would be empty. How can I "clean" these
controls?

Thank you,
Vanessa


Morten Wennevik said:
Hi Vanessa,

I've attached some code demonstrating how you can do this using business
objects. You should be able to do it with relational tables as well, but I'm
not so familiar using tables as datasource. The code assumes you have a
DataGridView, ComboBox and TextBox on your Form


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

ClassA a = new ClassA("A");
BindingSource sourceA = new BindingSource(a, "");
BindingSource sourceB = new BindingSource(sourceA, "BList");
BindingSource sourceC = new BindingSource(sourceB, "CList");
dataGridView1.DataSource = sourceB;
comboBox1.DataSource = sourceC;
comboBox1.DisplayMember = "Name";
textBox1.DataBindings.Add("Text", sourceC, "Id");
}
}

public class ClassA
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassB> _bList;

public BindingList<ClassB> BList
{
get { return _bList; }
set { _bList = value; }
}
public ClassA(string name)
{
Name = name;
BList = new BindingList<ClassB>();

BList.Add(new ClassB(Name + " B 1"));
BList.Add(new ClassB(Name + " B 2"));
}
}

public class ClassB
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private BindingList<ClassC> _cList;

public BindingList<ClassC> CList
{
get { return _cList; }
set { _cList = value; }
}
public ClassB(string name)
{
Name = name;
CList = new BindingList<ClassC>();

CList.Add(new ClassC(Name + " C 1"));
CList.Add(new ClassC(Name + " C 2"));
}
}

public class ClassC
{
static int count = 0;
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}

private int _id;

public int Id
{
get { return _id; }
set { _id = value; }
}
public ClassC(string name)
{
Name = name;
Id = count++;
}
}


--
Happy Coding!
Morten Wennevik [C# MVP]


:

Hi Morten!

Let me explain better what I want to do.

My database has the following tables:

Table A - the main table that is shown in the form. It has a field that is a
key into Table B;
Table B - it is related to Table A and it is a combobox in the form. It has
a field that is a key into Table C;
Table C - it is related to Table B and it has a description field to show in
a textbox.

So, my question is, how can I make the binding to the textbox that is on
Table C? What I want is to show the description field from Table C, whose key
is on the Table B (combobox).

Thank you,
Vanessa

:

Hi Vanessa,

I suspect you get some invalid data breaking the databinding. Try handling
the DataError event of the BindingSource.

It is a bit unclear what you have databound and not, and in fact what
controls you have. What is the relationship between the (data)grid and the
combobox? Are you databinding a ComboBox to one BindingSource and a DataGrid
to another, while the TextBox remains unbound and is updated manually when a
change occurs in either the ComboBox or the DataGrid?

Other things to try. Bind the TextBox to the same BindingSource as the
ComboBox rather than updating it in the CurrentChanged event (although this
won't work if you use the same TextBox to display values from another
BindingSource as well). Try handling the ListChanged event, which should
fire if the underlying datasource changes. If the list is changed, get the
BindingSource.Current value and update the TextBox accordingly.



--
Happy Coding!
Morten Wennevik [C# MVP]


:

Hi All!

I am with a situation where I am not getting the right updating to the
form's fields. The situation is the following one:

I have one combobox and one textbox. I am using the CurrentChanged event of
the BindingSource of the combobox to update the textbox. When selecting an
item in the combobox or when selecting a row in the grid, it is updating the
textbox correctly. The problem is when I apply a filter in the grid, and then
the grid has no rows. I already made the following attempts:

- When there is no row in the grid, the event is not called, and textbox
mantains the previous content;
- If I call the CurrentChanged event directly when there is no rows in the
grid, in this case I clean up the textbox, but when I apply a filter again in
the grid and the position of the combobox does not modify (that is, it is in
the same register), the CurrentChanged is not called, and edit is blank
(because I cleaned before);
- I already tried to use “combo.SelectedIndex = -1†but also did not worked.

Does someone has any idea of how can I solve this situation?

Thank you for any suggestion!
Vanessa
 

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