Disabling Controls when BindingSource.Count == 0

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jehugaleahsa@gmail.com

    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
  • G.S.

    #2
    Re: Disabling Controls when BindingSource.C ount == 0

    On Sep 30, 10:15 am, "jehugalea...@g mail.com" <jehugalea...@g mail.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.

    Comment

    • G.S.

      #3
      Re: Disabling Controls when BindingSource.C ount == 0

      On Sep 30, 11:09 am, "G.S." <gstoy...@gmail .comwrote:
      On Sep 30, 10:15 am, "jehugalea...@g mail.com" <jehugalea...@g mail.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:

      Comment

      • Peter Duniho

        #4
        Re: Disabling Controls when BindingSource.C ount == 0

        On Tue, 30 Sep 2008 07:15:20 -0700, jehugaleahsa@gm ail.com
        <jehugaleahsa@g mail.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
        DataSourceChang ed 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()
        {
        InitializeCompo nent();

        dataGridView1.D ataSourceChange d +=
        dataGridView1_D ataSourceChange d;
        }

        private void dataGridView1_D ataSourceChange d(object sender,
        EventArgs e)
        {
        DataGridView dgv = (DataGridView)s ender;

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

        source.ListChan ged += delegate(object sender,
        ListChangedEven tArgs 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.L istChanged 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

        Comment

        • jehugaleahsa@gmail.com

          #5
          Re: Disabling Controls when BindingSource.C ount == 0

          On Sep 30, 11:46 am, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
          wrote:
          On Tue, 30 Sep 2008 07:15:20 -0700, jehugalea...@gm ail.com  
          >
          <jehugalea...@g mail.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  
          DataSourceChang ed 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()
                   {
                       InitializeCompo nent();
          >
                       dataGridView1.D ataSourceChange d +=  
          dataGridView1_D ataSourceChange d;
                   }
          >
                   private void dataGridView1_D ataSourceChange d(object sender,  
          EventArgs e)
                   {
                       DataGridView dgv = (DataGridView)s ender;
          >
                       if (dgv.DataSource != null)
                       {
                           BindingSource source = (BindingSource) dgv.DataSource;
          >
                           source.ListChan ged += delegate(object sender,  
          ListChangedEven tArgs 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.L istChanged 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.Collecti ons.Generic;
          using System.Text;
          using System.Componen tModel;
          using System.Windows. Forms;
          using PowerBillingUI. Controls;

          namespace PowerBillingUI. Helpers
          {
          [ProvideProperty ("DisableWhenUn bound", typeof(Control) )]
          public class DisableHelper : Component, IExtenderProvid er
          {
          private class Handlers
          {
          public ListChangedEven tHandler ListChangedHand ler;
          public EventHandler EnableChangedHa ndler;
          }

          private IndirectBinding Source bindingSource; // just think of
          this as a BindingSource
          private IDictionary<Con trol, Handlerslistene rs;
          private bool enabled;

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

          public bool Enabled
          {
          get
          {
          return enabled;
          }
          set
          {
          if (bindingSource != null && enabled)
          {
          foreach (KeyValuePair<C ontrol, Handlerspair in
          listeners)
          {
          bindingSource.L istChanged -=
          pair.Value.List ChangedHandler;
          pair.Key.Enable dChanged -=
          pair.Value.Enab leChangedHandle r;
          }
          }
          enabled = value;
          if (enabled && bindingSource != null)
          {
          foreach (KeyValuePair<C ontrol, Handlerspair in
          listeners)
          {
          bindingSource.L istChanged +=
          pair.Value.List ChangedHandler;
          pair.Key.Enable dChanged +=
          pair.Value.Enab leChangedHandle r;
          }
          }
          }
          }

          public IndirectBinding Source BindingSource
          {
          get
          {
          return bindingSource;
          }
          set
          {
          bindingSource = value;
          }
          }

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

          [DefaultValue(fa lse)]
          public bool GetDisableWhenU nbound(Control control)
          {
          return listeners.Conta insKey(control) ;
          }

          public void SetDisableWhenU nbound(Control control, bool
          disableWhenUnbo und)
          {
          Handlers handlers;
          if (!listeners.Try GetValue(contro l, out handlers))
          {
          handlers = null;
          }
          if (handlers != null)
          {
          if (bindingSource != null)
          {
          bindingSource.L istChanged -=
          handlers.ListCh angedHandler;
          }
          control.Enabled Changed -=
          handlers.Enable ChangedHandler;
          handlers = null;
          }
          if (disableWhenUnb ound)
          {
          handlers = new Handlers();
          handlers.Enable ChangedHandler = (EventHandler)
          delegate(object sender, EventArgs e)
          {
          control.Enabled = bindingSource.C ount 0;
          };
          handlers.ListCh angedHandler =
          (ListChangedEve ntHandler)
          delegate(object sender, ListChangedEven tArgs e)
          {
          control.Enabled = !control.Enable d; // fires
          EnableChangedHa ndler
          };
          }
          if (handlers == null)
          {
          listeners.Remov e(control);
          }
          else
          {
          listeners[control] = handlers;
          }
          }
          }
          }

          Comment

          • jehugaleahsa@gmail.com

            #6
            Re: Disabling Controls when BindingSource.C ount == 0

            Nevermind. It does work so long as you set Enabled at the right time.

            Comment

            Working...