views:

672

answers:

2

I have what must be a typical catch-22 problem. I have a .NET WinForm control that contains a textbox and a checkbox. Both controls are data bound to properties on a data class instance. The textbox is for price, the check box to indicate that the price is a price override. Also on the data class is a property that holds the item's original price.

I would like the controls to respect the following rules:

  • When the user enters a value into the price textbox, the checkbox is automatically checked to indicate they are overriding the price value
  • When the check box is un-checked, the item's price is restored to the original price.

When the user unchecks the checkbox, the event handler tests the checked state, and sets the item's price property to the original price value. However, the price value being databound, a bind event is fired, which updates the textbox value, which fires the text changed event handler which re-checks the checkbox.

I've attempted to trap the conditions where I'm explicitly updating something that would trigger a control change event. This only works for part of it though. The textbox change event fires other times that are outside my control, such as when databinding fires when the form is initially shown.

I've been searching around and I guess I'm just not coming up with the right search terms to find what I'm looking for. It seems that databinding is all wonderful and nifty until you need to do something pratical with it, like having two bound controls interact with each other. There just doesn't seem to be a way to discriminate between what triggered the control events.

I've also looked at the events available on the binding source component but there doesn't seem to be anything there that is any more useful. I can handle the event that fires after binding is complete, but that's after the problems occur.

Anyone have any suggestions?

A: 

Have you considered handling the TextBox TextChanged event to handle the CheckBox state instead of binding it?

You could then compare the current TextBox value to the original and determine if the CheckBox should be true or false.

Another thought is you could inherit TextBox and add properties to your custom TextBox so the TextBox handles it's own state. For example it can have a read-only IsOriginal property.

I don't have VS installed right now so I didn't verify it, let me know if you want an example.

Chris Roland
+3  A: 

I would suggest not handling the logic in the form code, but rather in the data class. All you need in the form is a couple of lines to set up the data binding. The data class can then take care of the rest:

Form

Private _dc As DataClass

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    _dc = New DataClass
    txtPrice.DataBindings.Add("text", _dc, "Price")
    chkOverride.DataBindings.Add("checked", _dc, "override")
End Sub

Data Class

Private _originalPrice As Double = 50

Private _price As Double = _originalPrice
Public Property Price() As Double
    Get
        Return _price
    End Get
    Set(ByVal value As Double)
        If (_price <> value) Then
            _price = value
            Override = _price <> _originalPrice
        End If
    End Set
End Property


Private _override As Boolean
Public Property Override() As Boolean
    Get
        Return _override
    End Get
    Set(ByVal value As Boolean)
        If _override <> value Then
            _override = value
            If Not _override Then Price = OriginalPrice
        End If
    End Set
End Property

No need to handle any CheckedChanged or TextChanged events in the form.

Tom Juergens
I was thinking the databinding still might cause a problem because of how it updates so much. But from what I've seen from tests of the BindingComplete event, this still may work. Plus, it puts the rule into the data model. I've worked around the problem for now, but I'll try this if I can.
Peter