开发者

how to intercept WPF binding for custom processing

Say you have a window with 20 textboxes on it which are all bound to different BLL classes. How do I intercept a value being passed from a textbox to a property when binding with wpf? I'm looking for a generic solution instead of doing this for ever开发者_StackOverflowy property.

I can inherit from the Binding class, but is there an event in that class I can listen to whenever data is passed from an uielement to a property? Or is there a better solution?


The Binding has a Converter property to which you can assign a class that implements IValueConverter. If you can inherit from binding, maybe you can set the Converter in that specialization and go on with that.


I think the solution youn are looking for is a value converter. This msdn page describes how to do this -> http://msdn.microsoft.com/en-us/library/ms752347.aspx#data_conversion.


I may be mistaking but have you tried with converter? Here's a pretty good site you can check it out:

http://www.switchonthecode.com/tutorials/wpf-tutorial-binding-converters


I would like to vote on all three answers but I don't have the reputation for it. Vote for this and i'll vote for you ;)

I solved my problem thanks to you guys!

Here's what I did:

  1. Create a new ValueConverter with an event SourceUpdated that fires whenever a value is passed trough it.
  2. Inherit all our existing converters from it.
  3. Create a new Binding class (which inherits from Binding), in the constructor see if there's a Converter already, if there isn't create one:

    if (Converter == null) {
        Converter = new GcBindingConverter();
    }
    
    if (Converter.GetType().IsAssignableFrom(typeof(GcBindingConverter))) {
        ((GcBindingConverter)Converter).SourceUpdated += SourceUpdatedHandler;
    }
    
  4. On each form that needs this functionality wire the events to an event handler, I've put the handler in our modelstate:

    static void WireDirtyBindings(DependencyObject element, ModelStateBase ModelState)
    {
        Binding bb = null;
        // find bindings on elements:
        if ((object.ReferenceEquals(element.GetType, typeof(TextBox)))) {
            bb = BindingOperations.GetBinding(element, TextBox.TextProperty);
        } else if ((object.ReferenceEquals(element.GetType, typeof(ComboBox)))) {
            bb = BindingOperations.GetBinding(element, ComboBox.SelectedValueProperty);
            // other objects...
        }
    
    
    if (bb != null) {
        // wire eventhandler to event:
        doWireHandler(bb, ModelState);
    }
    
    // Now, recurse through any child elements
    if (element is FrameworkElement || element is FrameworkContentElement) {
        foreach (object childElement in LogicalTreeHelper.GetChildren(element)) {
            if (childElement is DependencyObject) {
                WireDirtyBindings((DependencyObject)childElement, ModelState);
            }
        }
    }
    

    }

The only thing I have to write now for each form that has lots of data input is:

BaseBinding.WireDirtyBindings(this, _modelState);

5: In the form, bind the save changes button's enabled state to the modelstate property that says if there are any changes. I could also use an interface for this but since we already have something like a modelstate this is a good place to put it.

This works quite nicely with just a few lines of code. Now I don't have to worry about end users making lots of changes without saving it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜