Is it wise to bind to Enabled or other non-data Control properties?

Is it wise to bind to Enabled or other non-data Control properties?

Old forum URL: forums.lhotka.net/forums/t/6580.aspx


rsbaker0 posted on Sunday, March 08, 2009

I was working through some issues today in our application where certain controls on a form are enabled or disabled based on some combination of properties in the bound data.

I started to put this code in the directly UI, but immediately found it to be rediculously tedious. This was mainly because properties aren't typically posted back to the bound object until you tab out of a field. Ugh.

Then it occured to me I had seen previous references here to binding to the IsValid or IsSavable properties, and it turned out I could implement quite simple properties and just bind them to the Enabled property of the corresponding controls.

Are there any gotchas to doing this? It seems to work quite well and requires much less (and non-control specific) code.

RockfordLhotka replied on Sunday, March 08, 2009

It is absolutely fine to do that sort of binding. The only catch is that the IsXYZ properties are marked as non-bindable, so you need some intermediate object to expose them as bindable values (or use code-behind triggered off PropertyChanged) - but you've presumably already got that solved.

SonOfPirate replied on Tuesday, March 10, 2009

Yea, typically Enabled will be based on the current user's authorization or something similar but it is itself a UI property.  The same can be said for the Visible property on a control.

If you are concerned about mixing UI and business logic, I would caution you about exposing additional properties just for the UI.  For instance, does Enabled really make sense in another context, say a WCF service?  If so, go for it; otherwise, it may be that this logic is Presentation logic and not really business logic.  If that is the case, then I was suggest that it belongs in your code-behind, control or some other UI element.

JonnyBee replied on Monday, March 16, 2009

Hi,

From my experience I tend to databind only the data properties (the sequence of updates/events can be hard to debug).

Basically - whet you want to do is exactly what the ReadWriteAuthorization extender does. This extender calls the CanReadProperty and CanWriteProperty on your BO. By default the BO will call the AuthorizationEngine but you can also override the Can... methods. That way your BO will also protect iteself from allowing a UI programmer to write properties that should not be written to.

So in your BO:
        public override bool CanWriteProperty(string propertyName)
        {
            if (!base.CanWriteProperty(propertyName)) return false;

            if (ReadProperty("somePropertyName") == "someValue")
            {
                // make additional tests
                return false;
            }

            return true;
        }


And in your UI use the BindingSource.CurrentItemChanged event:
        private void rootBindingSource_CurrentItemChanged(object sender, EventArgs e)
        {
            readWriteAuthorization1.ResetControlAuthorization();
        }


or you could also use this method:
      someUIcontrol.Enabled = bo.CanWriteProperty(someUIControl.DataBindings["Text"].PropertyName);

/jonny

rsbaker0 replied on Tuesday, March 17, 2009

JonnyBee:
Hi,

From my experience I tend to databind only the data properties (the sequence of updates/events can be hard to debug).

Basically - whet you want to do is exactly what the ReadWriteAuthorization extender does. This extender calls the CanReadProperty and CanWriteProperty on your BO. By default the BO will call the AuthorizationEngine but you can also override the Can... methods. That way your BO will also protect iteself from allowing a UI programmer to write properties that should not be written to.

In my particular use case, writability is more related to the state of the object than authorization, although you could certainly retask CanWriteProperty for this purpose.

I have some issues with both the ReadWriteAuthorization control (although I am working on my own version of it) because it ends up disabling controls rather than setting them read only because the ReadOnly property isn't in the expected location in DevExpress controls.

Also, the bindings will respond almost instantly to data changes in the object without any additional code required in the user interface. With the extender control, I think you have to manually call ResetControlAuthorization -- and know which control events in the UI require doing this -- whereas a binding to Enabled works automagically.

Copyright (c) Marimer LLC