Thursday, January 24, 2008

WPF Data Binding in code

Recently, I was working on a WPF prototype for our application. Unfortunately, we need some features in a grid control and some other controls that won't allow us to use the WPF grids available on the market. For this reason, we need to use the Infragistics grid (the same one we've used in the past), the WinForms version.

Unfortunately, we also need to have docking (VS 2005 style) and tabbed MDI. Since docking has flyout controls, and WPF z-order doesn't work right with WinForms, we need to host our application in Windows Forms framework.

When you have a windows forms control in a WPF layout, the windows forms control (in the WindowsFormsHost control of WPF) doesn't participate in the z-order the way you might expect. Unfortunately, windows HWNDs don't support layering like WPF (DirectX) does, instead each HWND owns its part of the screen (except for areas overlapped by overlapping windows). Transparency in HWNDs is done by 'hacks', not builtin support.

Due to this structure, winforms controls must be rendered 'on top' of WPF content, when you host winforms in WPF windows. This means my flyout windows will show up "under" the winforms window, rather than on top of it like you'd expect. Anyway, the only way to get around this is to host WPF controls in WinForms rather than the other way around.



One of the real benefits of using WPF is the XAML markup and the ability to do data binding so easily in your layouts. Unfortunately, at first glance, this seems to be lost when you switch to WPF controls on top of a WinForms layout. Don't fear, all is not lost.

Fortunately, even though you can't use XAML markup to define your data binding, you can programmatically add bindings to your winforms layout. For instance, we have a infragistics grid (a winforms control) that lists the 'items' in our browser that people can choose to look at. On the other hand, we have WPF controls that react to which item is selected in the browser grid. It'd be nice if we could bind the WPF controls to a property on the other control so that they are automatically updated when necessary.

The way I did this was to create a DependencyObject that contains my properties for the grid that I'd like to bind to - in particular one of them was CurrentItem. The properties are DependencyProperty-based. Now, I needed one-way binding to update my WPF controls when the current item changed in the grid, but just in case, I set up my code to support two way binding, so that if I chose to set the value of the property from other parts of my code, I could do so safely and have everything update properly.

So, now I have a DO with a DP. When I register the DP, I created a update method so that I could trigger code when the property was changed - this is done by adding a delegate to the UIPropertyMetadata constructor passed in the DependencyProperty.Register call. To expose this DO to my clients (I've called it BindingInterfaceObject), I make a property on my UserControl (that contains the Infragistics Grid) called BindingInterface and create an instance of the BindingInterfaceObject in the constructor of the UserControl. I give it access to the UserControl's private members by making it a nested class and passing the 'this' pointer to its constructor.

In order to bind to it, I need to set bindings on my WPF controls. I do this by creating a Binding object (System.Windows.Data.Binding) with the name of the property in BindingInterfaceObject that I care about (in my case CurrentItem) and pass this binding object to the SetBinding method on the WPF controls.

Voila! I now have WPF controls binding to changes in a non-WPF control. The only thing I have to do now is set the CurrentItem property whenever the appropriate event occurs on the grid. I do this by handling those events in my UserControl and setting the BindingInterface.CurrentItem as appropriate.

I can provide sample code if you're interested. Just ask.

Tuesday, October 30, 2007

Raymond Chen - "The Old New Thing" (best book ever)

This is the most interesting non-technical (mostly) computer book I've ever seen! You owe it to yourself to check out Raymond Chen's blog (here) and buy his new book "The Old New Thing". It's great - I'm either laughing or totally nose down entrenched in reading this book - it's so interesting and at times funny too.

To save you having to look it up, it's a book on the historical development of windows and the 'why' in windows, rather than the 'how'. There are some really great insights here, especially about UI design, but there are also some amazing tidbits that explain questions that have been floating around in my head for some time (like what's the deal with GlobalAlloc, LocalAlloc, and all that crap!).

Anyway, check it out - you can buy it by going to his blog (here) and clicking the book image in the upper right corner.

Friday, October 19, 2007

Away for a while...

So, I've been away for a while. Sorry about that. I've got a bunch of new topics I'd like to write about, so many I can't choose which to do first.

1) OpenXML - this is way cool!
2) More about attributes and their use in .NET - building a binary file system engine.
3) WiX
4) .NET 3.0 System.IO.Packaging and it's use for custom apps...
5) .NET 2.0, 3.0, 3.5 relationships and compatibility between them...
6) DLLs, dependencies, and best practices for COM objects that use non-COM dll's for inprocess use.
7) Benefits of MS Gold Partnership.
8) MG-ALFA planned improvements (at least the ones I can talk about)...

Not sure - any preferences - please email me...

Tuesday, March 20, 2007

Joel on Software

Good book, been recommended to me several times in the past, but I finally bought it with the 20% discount here at SD West 2007's book store...

The details are "Joel on Software" by "Joel Spolsky"... Get a copy yourself. Also, check out Joel's web site at http://www.joelonsoftware.com

Friday, January 26, 2007

Playing with attributes

I'm sure by now you've seen all sorts of .NET framework attributes that can be applied to various pieces of code. The most notable of these in my code are FlagsAttribute (for enums), and the XML serialization / Web Services ones (XmlElementAttribute, XmlAttributeAttribute, etc., and WebServiceAttribute). These are very nice and unleash all kinds of built-in behavior in the framework, but did you know you can make your own attributes and use them for your own purposes? That's what this blog entry is all about!

For me, one of the most common problems I face is one in which I would like to use an enumeration for a class member that has a list of choices. Of course, this is a no-brainer to use an enum for this, but often I want to go one step further. Often, I'd like to limit the enum's choices for the class member, based on the value of one or more of the other class members. This problem is very common in heirarchies where you have a shared base class that you want to support a member in that can have values that aren't always applicable to the object.

Let's say for the sake of argument that you have a class A with members x, y, and z. The z member should be a choice of z1, z2, or z3, but each of these choices is only available when the following conditions hold:


ConditionAvailability
x > 0, y anythingz1 z2 available, z3 not
x = 0, y > 0z1 available, z2, z3 not
x = 0, y < 0z2 available, z1, z3 not
x < 0, y anythingz3 available, z1, z2 not

We can see that these rules can be distilled into a separate "test function" for each value of z. For z1, it's available if x>0 (x == 0 && y>0). For z2, it's available if x>0 (x == 0 && y<0). For z3, it's available if x<0 only.

Now, I crashed my compiler in the process of trying to use anonymous delegates to express these conditions. Unfortunately, that doesn't seem to work. However, we can package these three tests into a helper class that provides static methods to perform these tests. For instance, let's make a class ZValueTests as follows:

  public static class ZValueTests
{
public static bool TestForZ1(int x, int y)
{
return x>0 (x == 0 && y>0);
}

public static bool TestForZ2(int x, int y)
{
return x>0 (x == 0 && y<0);
}

public static bool TestForZ3(int x, int y)
{
return x<0;
}
}

Now that we have these tests, we can use them in an attribute that we apply to each of our enum values. Let's first define our attribute class. We'll call it ValidForAttribute, and it must derive from the Attribute class to be known by the compiler. We'll have to use reflection to call the test functions, so this will be a fun demo in many ways! Here's our attribute declaration.

  [AttributeUsage(AttributeTargets.Field)]
public class ValidForAttribute : Attribute
{
private SR.MethodInfo _Test;

public ValidForAttribute(
Type TestClass,
string MethodName)
{
SR.MethodInfo mi
= TestClass.GetMethod(MethodName);
// assertions omitted for brevity
_Test = mi;
}

public bool Test(int x, int y)
{
return (bool)_Test.Invoke(
null,
new object[] { x, y });
}
}

As you can see from the declaration, we'll need to specify our attribute using the type of the class that implements our tests, and the name of the method on that class. This is because we can't use non-constant expressions in the attribute initializer (a pretty big limitation if you ask me), so we can't even use delegate creation expressions, much less anonymous methods! Anyway, this works, it's just a little less pleasant than I would have liked.

Now, we need to declare our actual Enum. You'll see it will be very easy and will look something like the following:

  public enum ZValue
{
[ValidFor(typeof(ZValueTests), "TestForZ1")]
z1,
[ValidFor(typeof(ZValueTests), "TestForZ2")]
z2,
[ValidFor(typeof(ZValueTests), "TestForZ3")]
z3
}

This is very pleasant as it very clearly defines the test functions that apply to each z value. Of course, one unpleasant thing is that the types of these functions cannot be checked until runtime (that's what the asserts that are omitted from the code in the attribute do). I would recommend even throwing an exception if the function isn't declared right from the constructor of the attribute, but that may be a bit harsh.

Now, I've shown how you can declare the enums, attribute class, and test class - but what we really want to see is the validation in action, right? So, here we go. If we declare the class A as follows:

public class A {
ZValue _z;

bool ValidateZ(int x, int y, ZValue z) {
SR.FieldInfo fi = typeof(ZValue)
.GetField(Enum.GetName(
typeof(ZValue), z));
// test all attrs (ValidForAttribute)
if(fi != null)
foreach(ValidForAttribute vfa
in fi.GetCustomAttributes(
typeof(ValidForAttribute),
true))
if (vfa.Test(x, y))
return true;
// ret false if enum not found,
// or no attrs found returning true
return false;
}

public int x, y;
public ZValue z
{
get { return _z; }
set {
if(ValidateZ(x, y, value))
_z = value;
else
throw new Exception(
string.Format(
"Invalid z: ({0}, {1}, {2})",
x, y, z));
}
}
}

then the code will validate a new value of z against x and y before setting the internal field (_z) to that value. An exception will be raised if the value is invalid. This may seem like a lot of work, instead of just validating z inside the z "set" accessor. That's true, it is. However, the real advantage to this is that the validation code can be used in other ways. For instance, consider if we wanted a list of valid values for z (for a UI, for instance) given a particular value of x and y. We can write the following code:

public static ZValue[] ValidZs(int x, int y) {
List<ZValue> zv = new List<ZValue>(
(IEnumerable<ZValue>)
Enum.GetValues(typeof(ZValue)));
zv.RemoveAll(new Predicate<ZValue>(
delegate(ZValue v)
{
SR.FieldInfo fi = typeof(ZValue)
.GetField(Enum.GetName(
typeof(ZValue),
v
));
if (fi != null)
foreach (ValidForAttribute vfa
in fi.GetCustomAttributes(
typeof(ValidForAttribute),
true))
if (vfa.Test(x, y))
return false;
return true;
}
));
}

Hope you found this interesting! Email with questions, if you have them!

Saturday, January 6, 2007

Anonymous Delegates in C#

A friend asked me recently what features other than Generics I really liked in C# 2.0. I mentioned that the anonymous delegate is one of those features. So, you might ask, what is an anonymous delegate? First of all, for those of you who don't know what delegates are, they are the C# equivalent of a function pointer, sortof.

A delegate is a strongly typed method pointer, that stores both the method reference and the object reference on which the method is defined. Delegates are declared with the syntax:

[access] delegate [return type]
[delegate name] ( [param signatures] )

where [access] is an access modifier (optional) - public, private, protected, or internal, return type is the return type of methods that will be pointed to by the delegate (or void), and the other items are relatively self-explanatory.

Now. That's how a delegate "type" is declared. However, anonymous delegates aren't really delegate types - they're delegate instances. Let's say we have a delegate called BinaryIntegerOperation declared as:

public delegate int
BinaryIntegerOperation (int a, int b);

This declaration gives us a delegate type called BinaryIntegerOperation. If we want to create a delegate instance, we need to pass the name of a function with the appropriate signature to this delegate's constructor during a invocation of the new operator. Let's assume that we have a class declared as:

public class Adder {
public int Add(int x1, int x2) {
return x1 + x2;
}
}

Let's also assume that we have some instance of the Adder class, referenced by a variable called myAdder, within the context of the code we care about. The code to construct a delegate instance of BinaryIntegerOperation using the Add method of our myAdder object instance would look like:

...
BinaryIntegerOperation op
= new BinaryIntegerOperation(
myAdder.Add);
...

and the code to invoke this delegate would look like:

int result = op(value1, value2);

(just like a normal method call).

Now, let's say that instead of declaring an Adder class, we just wanted to be able to pass some simple implementation of the BinaryIntegerOperation delegate's method signature to the delegate's constructor so that we could use it in a context that needs a BinaryIntegerOperation instance. We can do the following, instead of declaring a Adder object altogether:

BinaryIntegerOperation op
= new BinaryIntegerOperation(
delegate (int a, int b) {
return a + b;
});

As you can see from this code, the code for the delegate instance is actually placed inline using the delegate keyword, along with the parameter signatures of the method. C# will automatically create a class, instance, and method for us, so we don't have to do so ourselves.

You might say, what is the advantage of this? I use this feature very extensively, often in code dealing with list filtering or searching.

Let's say you have a list of integers, and you want to determine if any of them is larger than a particular value (say 10).

Consider the code (list is List<int>)

bool bigger = false;
foreach(int item in list) {
if(item > 10) {
bigger = true;
break;
}
}

you could instead write it as:

bool bigger =
-1 != list.FindIndex(
new Predicate<int>(
delegate (int x) {
return x > 10;
}));

where, again, list is List<int>.

Friday, January 5, 2007

The ClickOnce reference (on MSDN)

Just in case you want to learn a bit about ClickOnce yourself, from the source, you can do so on the MSDN site here: http://msdn2.microsoft.com/en-us/library/6ae39a7c(VS.80).aspx