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:
- Create a new ValueConverter with an event SourceUpdated that fires whenever a value is passed trough it.
- Inherit all our existing converters from it.
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; }
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.
精彩评论