471,578 Members | 1,424 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,578 software developers and data experts.

Disabling Controls when BindingSource.Count == 0

Hello:

I am sure this question comes up a lot. I need to disable the controls
on my Windows forms so that when the BindingSource is empty some the
controls bound to it will be disabled.

This will make it clear to the user that they have to create a new
item first before they start working.

This needs to be an easy process because there are many, many forms.
We can't just go through every control and disable it since some
controls need to always be enabled. My hope was to perform the
operation with some sort of binding.

We have considered other options, such as automatically inserting when
the binding source is empty, but that comes with its own set of
problems. We think disabling is probably the most straighforward way
to eliminate the problem.

Any insight would be helpful.

Thanks,
Travis
Sep 30 '08 #1
5 4680
On Sep 30, 10:15*am, "jehugalea...@gmail.com" <jehugalea...@gmail.com>
wrote:
Hello:

I am sure this question comes up a lot. I need to disable the controls
on my Windows forms so that when the BindingSource is empty some the
controls bound to it will be disabled.

This will make it clear to the user that they have to create a new
item first before they start working.

This needs to be an easy process because there are many, many forms.
We can't just go through every control and disable it since some
controls need to always be enabled. My hope was to perform the
operation with some sort of binding.

We have considered other options, such as automatically inserting when
the binding source is empty, but that comes with its own set of
problems. We think disabling is probably the most straighforward way
to eliminate the problem.

Any insight would be helpful.

Thanks,
Travis
This group is focused on the C# language itself, not WinForms, so
maybe another group may provide better advice, I do remember however
seeing a discussion here in the last month or so about something
similar.

My post then was about disabling a bunch of controls by placing them
in a panel and only disabling the panel.

If I'm not mistaken, you want to look into the events that
BindingSource exposes and handle enable/disable there. If that doesn't
work, then you need to handle individual control's binding event - you
could probably write a single handle and point all relevant controls
to it.
Sep 30 '08 #2
On Sep 30, 11:09*am, "G.S." <gstoy...@gmail.comwrote:
On Sep 30, 10:15*am, "jehugalea...@gmail.com" <jehugalea...@gmail.com>
wrote:


Hello:
I am sure this question comes up a lot. I need to disable the controls
on my Windows forms so that when the BindingSource is empty some the
controls bound to it will be disabled.
This will make it clear to the user that they have to create a new
item first before they start working.
This needs to be an easy process because there are many, many forms.
We can't just go through every control and disable it since some
controls need to always be enabled. My hope was to perform the
operation with some sort of binding.
We have considered other options, such as automatically inserting when
the binding source is empty, but that comes with its own set of
problems. We think disabling is probably the most straighforward way
to eliminate the problem.
Any insight would be helpful.
Thanks,
Travis

This group is focused on the C# language itself, not WinForms, so
maybe another group may provide better advice, I do remember however
seeing a discussion here in the last month or so about something
similar.

My post then was about disabling a bunch of controls by placing them
in a panel and only disabling the panel.

If I'm not mistaken, you want to look into the events that
BindingSource exposes and handle enable/disable there. If that doesn't
work, then you need to handle individual control's binding event - you
could probably write a single handle and point all relevant controls
to it.- Hide quoted text -

- Show quoted text -
.... something along those lines:
http://www.codeproject.com/KB/vb/Dat...OnlyProps.aspx
Sep 30 '08 #3
On Tue, 30 Sep 2008 07:15:20 -0700, je**********@gmail.com
<je**********@gmail.comwrote:
I am sure this question comes up a lot. I need to disable the controls
on my Windows forms so that when the BindingSource is empty some the
controls bound to it will be disabled.

This will make it clear to the user that they have to create a new
item first before they start working.

This needs to be an easy process because there are many, many forms.
We can't just go through every control and disable it since some
controls need to always be enabled. My hope was to perform the
operation with some sort of binding. [...]
You don't have enough information in your question for us to understand
exactly what you're doing. For example, what kind of control are you
using? What kind of data source is bound to the control? Is it always an
instance of BindingSource? Or do you bind with other types as well?

Generally speaking, I'm not aware of any particular feature in data
binding that does exactly that. But you can easily implement what you're
asking using the appropriate events on the objects you're dealing with.

In particular, when you create the controls, subscribe a handler to the
DataSourceChanged event. In that event, depending on the type of the data
source, subscribe a handler to the appropriate event (e.g. ListChanged)
that will enable/disable the control as appropriate for the data.

For example, let's assuming we're binding a BindingSource instance to a
DataGridView control. The above might look something like this:

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

dataGridView1.DataSourceChanged +=
dataGridView1_DataSourceChanged;
}

private void dataGridView1_DataSourceChanged(object sender,
EventArgs e)
{
DataGridView dgv = (DataGridView)sender;

if (dgv.DataSource != null)
{
BindingSource source = (BindingSource)dgv.DataSource;

source.ListChanged += delegate(object sender,
ListChangedEventArgs e)
{
BindingSource source = (BindingSource)sender;

dgv.Enabled = source.Count 0;
}
}
}
}

The above assumes that if the binding source for a control is changed, the
source itself is discarded, never used again. If that assumption isn't
true, you'll have to include some code to unsubscribe the previous
BindingSource.ListChanged event handler, to ensure that the control
doesn't wind up getting enabled or disabled spuriously (or worse, after
it's been disposed). This is kind of a pain, because you'd have to keep a
reference to the previous DataSource, but it's doable and necessary in
that situation. (It's unfortunate that the "XXXChanged" events in .NET
don't include an easy way to get at the old value, but that's what we're
stuck with).

Pete
Sep 30 '08 #4
On Sep 30, 11:46*am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Tue, 30 Sep 2008 07:15:20 -0700, jehugalea...@gmail.com *

<jehugalea...@gmail.comwrote:
I am sure this question comes up a lot. I need to disable the controls
on my Windows forms so that when the BindingSource is empty some the
controls bound to it will be disabled.
This will make it clear to the user that they have to create a new
item first before they start working.
This needs to be an easy process because there are many, many forms.
We can't just go through every control and disable it since some
controls need to always be enabled. My hope was to perform the
operation with some sort of binding. *[...]

You don't have enough information in your question for us to understand *
exactly what you're doing. *For example, what kind of control are you *
using? *What kind of data source is bound to the control? *Is it always an *
instance of BindingSource? *Or do you bind with other types as well?

Generally speaking, I'm not aware of any particular feature in data *
binding that does exactly that. *But you can easily implement what you're *
asking using the appropriate events on the objects you're dealing with.

In particular, when you create the controls, subscribe a handler to the *
DataSourceChanged event. *In that event, depending on the type of the data *
source, subscribe a handler to the appropriate event (e.g. ListChanged) *
that will enable/disable the control as appropriate for the data.

For example, let's assuming we're binding a BindingSource instance to a *
DataGridView control. *The above might look something like this:

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

* * * * * * *dataGridView1.DataSourceChanged += *
dataGridView1_DataSourceChanged;
* * * * *}

* * * * *private void dataGridView1_DataSourceChanged(object sender, *
EventArgs e)
* * * * *{
* * * * * * *DataGridView dgv = (DataGridView)sender;

* * * * * * *if (dgv.DataSource != null)
* * * * * * *{
* * * * * * * * *BindingSource source = (BindingSource)dgv.DataSource;

* * * * * * * * *source.ListChanged += delegate(object sender, *
ListChangedEventArgs e)
* * * * * * * * *{
* * * * * * * * * * *BindingSource source = (BindingSource)sender;

* * * * * * * * * * *dgv.Enabled = source.Count >0;
* * * * * * * * *}
* * * * * * *}
* * * * *}
* * *}

The above assumes that if the binding source for a control is changed, the *
source itself is discarded, never used again. *If that assumption isn't*
true, you'll have to include some code to unsubscribe the previous *
BindingSource.ListChanged event handler, to ensure that the control *
doesn't wind up getting enabled or disabled spuriously (or worse, after *
it's been disposed). *This is kind of a pain, because you'd have to keep a *
reference to the previous DataSource, but it's doable and necessary in *
that situation. *(It's unfortunate that the "XXXChanged" events in .NET*
don't include an easy way to get at the old value, but that's what we're *
stuck with).

Pete
Thanks, Pete. That was informative. I kind of took your idea and made
an extender control. However, the dang thing doesn't work, and I can't
figure out why. If this topic is still alive, could you please look
and see. I'd appreciate it.

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using PowerBillingUI.Controls;

namespace PowerBillingUI.Helpers
{
[ProvideProperty("DisableWhenUnbound", typeof(Control))]
public class DisableHelper : Component, IExtenderProvider
{
private class Handlers
{
public ListChangedEventHandler ListChangedHandler;
public EventHandler EnableChangedHandler;
}

private IndirectBindingSource bindingSource; // just think of
this as a BindingSource
private IDictionary<Control, Handlerslisteners;
private bool enabled;

public DisableHelper()
{
listeners = new Dictionary<Control, Handlers>();
}

public bool Enabled
{
get
{
return enabled;
}
set
{
if (bindingSource != null && enabled)
{
foreach (KeyValuePair<Control, Handlerspair in
listeners)
{
bindingSource.ListChanged -=
pair.Value.ListChangedHandler;
pair.Key.EnabledChanged -=
pair.Value.EnableChangedHandler;
}
}
enabled = value;
if (enabled && bindingSource != null)
{
foreach (KeyValuePair<Control, Handlerspair in
listeners)
{
bindingSource.ListChanged +=
pair.Value.ListChangedHandler;
pair.Key.EnabledChanged +=
pair.Value.EnableChangedHandler;
}
}
}
}

public IndirectBindingSource BindingSource
{
get
{
return bindingSource;
}
set
{
bindingSource = value;
}
}

public bool CanExtend(object extendee)
{
return extendee is Control;
}

[DefaultValue(false)]
public bool GetDisableWhenUnbound(Control control)
{
return listeners.ContainsKey(control);
}

public void SetDisableWhenUnbound(Control control, bool
disableWhenUnbound)
{
Handlers handlers;
if (!listeners.TryGetValue(control, out handlers))
{
handlers = null;
}
if (handlers != null)
{
if (bindingSource != null)
{
bindingSource.ListChanged -=
handlers.ListChangedHandler;
}
control.EnabledChanged -=
handlers.EnableChangedHandler;
handlers = null;
}
if (disableWhenUnbound)
{
handlers = new Handlers();
handlers.EnableChangedHandler = (EventHandler)
delegate(object sender, EventArgs e)
{
control.Enabled = bindingSource.Count 0;
};
handlers.ListChangedHandler =
(ListChangedEventHandler)
delegate(object sender, ListChangedEventArgs e)
{
control.Enabled = !control.Enabled; // fires
EnableChangedHandler
};
}
if (handlers == null)
{
listeners.Remove(control);
}
else
{
listeners[control] = handlers;
}
}
}
}
Oct 2 '08 #5
Nevermind. It does work so long as you set Enabled at the right time.
Oct 2 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Mike | last post: by
4 posts views Thread by Dan =o\) | last post: by
3 posts views Thread by Fred Flintstone | last post: by
3 posts views Thread by =?Utf-8?B?cml2YWxAbmV3c2dyb3Vwcy5ub3NwYW0=?= | last post: by
reply views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by
reply views Thread by lumer26 | last post: by
reply views Thread by Vinnie | last post: by
1 post views Thread by lumer26 | last post: by
reply views Thread by lumer26 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.