Rediscovering the Obvious

…stumbling in the footsteps of greatness

Binding to local helper objects

without comments

“Hack” or “Good Thing” — What do you all think?

I wanted to factor out some minor calculations from one of my screen, things like updating a total based on the sum of some other balances. To support this, I created an object named BatchCalculator and added some get/set properties and a couple of get-only calculated properties. I wired up INotifyPropertyChanged, and then added a private property to my page. In OnInitialize I set up the initial values, and in the command handler for the page’s “save” command, I consume the values in building the calls to the other layers of the application. So far, so good… fairly clean design, everything’s happy, right?

Then I tried to bind to that object. UGH! It’s not a DependencyObject or connected as a DependencyProperty… nor does it feel to me like it should be, so I don’t want to set up the Binding object with RelativeSource or ElementName. I have an instance already, so adding a page resource as all the examples point out doesn’t help… or does it?

My only working approach was to build up the binding in Code, like this:

            Binding b = new Binding();
            b.Source = BatchCalculator;
            b.Path = new PropertyPath(“StartingBalance”);
            b.Mode = BindingMode.TwoWay;
            b.UpdateSourceTrigger = UpdateSourceTrigger.Default;
            _startingAmountTextBox.SetBinding(TextBox.TextProperty, b);

This, however is UGLY, and should be a single XAML line.

The Solution

 Based on http://msdn2.microsoft.com/en-us/library/ms750950.aspx, I realized that I could add a resource to the page’s collection in code behind, and then have it be available for a {StaticResource} or {DynamicResource} markup extension to target. Since StaticResource “strongly suggests” (AKA requires in most cases) that the object is already declared and isn’t forward referenced, I added this to my constructor (names changed to protect… Me):

        public MyPageClass()
        {
            // Must be added BEFORE InitializeComponent
            Resources.Add(“batchCalculator”, BatchCalculator);
           
            InitializeComponent();
            RegisterCommands();
        }

Then, everything happily works with XAML that looks like this (get/set properties):

<TextBox Text=”{Binding Source={StaticResource batchCalculator}, Path=StartingBalance, Mode=TwoWay, UpdateSourceTrigger=Default}”/> 

or, for the calculated fields,

                    <TextBox IsReadOnly=”True” Text=”{Binding Source={StaticResource batchCalculator}, Path=AmountOver, Mode=OneWay, UpdateSourceTrigger=Default}” />

Conclusion

So, for those out there with more wisdom than I, is this a good way of accomplishing the binding I need? Or, did I miss something obvious? Do I misunderstand how one of the other two binding source specifiers works?

Written by erwilleke

July 27th, 2007 at 9:02 am

Posted in Uncategorized

Leave a Reply