Well dynamic anonymous types weren't required...
So, I finally wrapped up the process of cleaning up the UI side of my prior project. I haven't completely generalized it yet, but then again, the server side isn't completely generalized yet either. It is just closer to that goal. My UI code was never written with the intent of generalization and there are a lot more classes and methods that would need cleaning up. So I'll only put that effort in if we decide we want this as a core control. My bet is that we will at some point. Adding visual cues to your data virtualization is invaluable in my opinion. And the drill down ability for slicing and dicing the data is also invaluable.
Anyway, after digging in and successfully generating dynamic types, anonymous types, and even to a degree dynamic anonymous type (not to mention building legitimate types and assemblies in memory using wrappers around the logic to emit CIL) and still getting nowhere I went back to my "happy place"; assume I made a bad presumption elsewhere, look for that fault and start back from there.
As is almost always the case when spending this much time and not getting a working efforts, I had indeed made a mistaken assumption. And there were hints along the way. But confirmation bias is a strong and misleading force. For reasons I haven't uncovered, despite explicitly stating a data member binding for my columns, the cells were ending up bound to the original object anyway and not the property I told it to bind to. My assumption that the data bindings were correctly giving me the correct DataContext was the mistake I made.
In the end, this was a good thing for two reasons. I got to learn some more approaches to building types dynamically, which is definitely something for which valid purposes do pop up for once in a while, and I ended up with a much more efficient solution which didn't rely on reflection or other risky runtime compilation strategies.
I ended up simply using a pre-compiled type with a Dictionary property (which I had already built earlier in my original attempt) and then creating my own column which took the index in the dictionary as a constructor parameter and intercepted the call creating the cell's UI element and rebound the DataContext to the element at that index. That custom class required a whopping 1 property, 1 constructor and overriding a method to add 4 lines of code. Runs lightning fast and more importantly, works.
In the end, this approach allows me to dynamically build a grid based on arbitrary data. Which is what I was trying for in the first place.
Anyway, after digging in and successfully generating dynamic types, anonymous types, and even to a degree dynamic anonymous type (not to mention building legitimate types and assemblies in memory using wrappers around the logic to emit CIL) and still getting nowhere I went back to my "happy place"; assume I made a bad presumption elsewhere, look for that fault and start back from there.
As is almost always the case when spending this much time and not getting a working efforts, I had indeed made a mistaken assumption. And there were hints along the way. But confirmation bias is a strong and misleading force. For reasons I haven't uncovered, despite explicitly stating a data member binding for my columns, the cells were ending up bound to the original object anyway and not the property I told it to bind to. My assumption that the data bindings were correctly giving me the correct DataContext was the mistake I made.
In the end, this was a good thing for two reasons. I got to learn some more approaches to building types dynamically, which is definitely something for which valid purposes do pop up for once in a while, and I ended up with a much more efficient solution which didn't rely on reflection or other risky runtime compilation strategies.
I ended up simply using a pre-compiled type with a Dictionary property (which I had already built earlier in my original attempt) and then creating my own column which took the index in the dictionary as a constructor parameter and intercepted the call creating the cell's UI element and rebound the DataContext to the element at that index. That custom class required a whopping 1 property, 1 constructor and overriding a method to add 4 lines of code. Runs lightning fast and more importantly, works.
In the end, this approach allows me to dynamically build a grid based on arbitrary data. Which is what I was trying for in the first place.
Comments
Post a Comment