I recently needed to use to make sure that a number entered into a text box was less than the value of a property on my view model.
Arguably, this sort of business logic might be better off inside my view model; possibly let the property get set regardless, then verify and do something with IDataErrorInfo to notify the GUI if it's wrong before updating my model data if required. But in this case I am binding straight onto a property which is held inside a class I cannot modify, so I decided to try and use WPF's built-in binding validation mechanism.
So far so good; off I went deriving from ValidationRule and overriding Validate, but I soon came a cropper trying to access the view model. The problem is that ValidationRule isn't a DependencyObject so I can't add a dependency property to bind my view model to, and the specifics of my usage (this TextBox is dynamically generated in a DataGrid in code, but that's for another blog post), meant that the solution suggested here didn't help me, the binding fails at the point the TextBox is created so never gets updated when it's finally set.
So after a bit of a dig about in the MSDN I found that if you set
ValidationStop = ValidationStep.UpdatedValue
on the ValidationRule the value parameter in the Validate method is the BindingExpression itself, from which you can query DataItem to get the binding source object that the expression uses (which in my case is my view model).
Great stuff, but now how do I get my actual value from the BindingExpression? I can't use SourceValue, or SourceItem, because even though under the debugger they show my value, they are both internal.
So along comes .Net 4.5 to the rescue with a new ResolvedSource property for BindingExpression which will return the binding source object, in this case the TextBox text property which means I can do something like this:
public class NumberIsGreaterThanVmValidationRule : ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { var result = new ValidationResult(true, null);
Today I revisited some old projects under Visual Studio 2010 to carry out some maintenance. The solution file contains a handful of C# code projects, and two Deployment Projects (vdproj). Every time I tried to build, it would succeed but I would be prompted with this dialog for each Deployment Project.
Clicking OK or closing the dialog would prompt another to pop-up, at least a dozen or so times before finally finishing the build.
A bit of digging about (some of the links provided in various forums posts have since become broken) and Microsoft released a hot fix back in April 2011 which you can find here. According to one post, the issue is down to a different hashing algorithm employed by Microsoft for generating GUIDs in SP1 of VS2010.
Any deployment projects created before SP1 and checked into source control will then attempt to update the component GUID and popup this error, although I seem to get this on every build if the .vdproj is checked in, regardless of whether VS2010 SP1 has previously updated the file.
Fortunately installing this hot fix makes the problem go away and stops me having to mash my enter key every time I want to build.