One thing has been really annoying me for a long time – when I was setting IsEnabled property on some WPF container to false all its contained controls automatically became disabled as well. Ok, that really wasn’t a source of my annoyance – it was rather expected. Really frustrating thing is that you are unable to scroll a DataGrid, to copy and paste a text from TextBox etc. One can say – but there is a ReadOnly property – and he’s going to be right, but unfortunately it’s available on only few of these controls. TextBox for instance has an IsReadOnly property and DataGrid control that I’m currently using has a ReadOnly property.

After a while of googling and finding nothing I decided to do it my way. At first I thought that it will be a great idea to have an attached property on one of container controls. That control could recursively look through all its children’s and decide whether it should be set to ReadOnly or Enabled. Few whiles later I had my code ready but something wasn’t right. When I was trying to iterate through my controls collection it turned out that my container is empty ? But it wasn’t. Ok, in fact it was at that moment, apparently the visual/logical tree is empty until the Window undergoes layout at least once. Now that was a pity. I had an option to do it by utilizing OnContentRendered(EventArgs e) event method but it would rather make my code ugly, dependent and evil.

Finally I decided do create some extension methods and set this property from code-behind. It’s still something that I’m not proud of, but well, it works. If someone has a better idea please don’t hesitate to write a comment or contact me.

Some code:

public static class ControlsExtensions
{
    public static void IsReadOnly(this GroupBox gb, bool isReadOnly)
    {
        RecurseTree(gb, isReadOnly);
    }

    // more extension methods for other containers...

    private static void RecurseTree(FrameworkElement control, 
                                    bool isReadOnly)
    {
        foreach (var c in LogicalTreeHelper.GetChildren(control))
        {                
            var frameworkElement = c as FrameworkElement;
            if (frameworkElement == null) continue;

            var tb = c as TextBox;
            if (tb != null)
            {
                tb.IsReadOnly = isReadOnly;
                continue;
            }

            var dg = c as SomeDataGrid;
            if (dg != null)
            {
                dg.ReadOnly = isReadOnly;
                continue;
            }

            if (c is GroupBox || c is DockPanel || c is Grid 
                || c is StackPanel || c is TabControl)
            {
                RecurseTree(frameworkElement, isReadOnly);
            }
            else
            {
                frameworkElement.IsEnabled = !isReadOnly;
            }
        }
    }
}

You might notice that I don’t repeat recursion for not container types – that is intentional in terms of my project, and it saves a few processor cycles.

I do think that somewhere out there is a more elegant solution, if you know one please let me know.

Technorati Tagi:

On 25th PG.NET meeting I’ve had presentation concerning S#arp Architecture. I do really like Steve Jobs style of presentation. I mean, I’m far from his abilities but I just believe in two things – 1. tell a story 2. don’t put to much information on a single slide. Unfortunately there is a downside of that kind of presentation - there is really nothing to show on internet unless you are going to record it live.

So here it is, almost no text (except the who-can-help.me slide – It was intentionally crowded to rise a question – are there too many third party frameworks and where is it going?). Oh and I’ve changed S#arp Architecture logo color (as a matter of fact I’ve inverted colors) to better match my background color :-)

Notes to remember:

  • while presenting your code live everything can happen, maybe it is better to record it first ? On the other hand doing real live coding is cool :-)
  • don’t forget what your next thing to show is while you are doing live code demonstration (again – recording first ?)
  • make more questions to audience, involve them (it works great to set their focus)

So far that’s all, I do really like being a speaker and I’m thinking already about next presentation.

Technorati Tagi: ,

Well it turns out that’s not so hard, Leon Bambrick @ secretgeek.net came out with a great idea! Just check it out, it’s worth it - The Ultimate Agent of WERF Destruction.

It took me a while to recover after that shocking idea :-) (back to normal = to get up from the floor)

We all struggle when it comes to user interface design. There is a tendency that brilliant ideas when compared with gray matter dissolve into something like this. I bet that you all seen (done) something similar. Well, let’s face the truth, unless you are making another search engine, FPP shooter or tic-tac-toe game you are probably building another enterprise app, and they are called enterprise because they tend to swallow a lot of data (over generalization was intended ;-). And yes, that data should be entered in them somehow, usually by human beings sitting in front of a computer. So we don’t have an option to run away from creating TextBoxes, ComboBoxes, Grids etc.

I have to admit that recently I was lost in pursuit of perfect input form design. In order to reduce overwhelming amount of user controls I decided to leverage some features of data grids. My reasoning was quite simple – if I need to show data in a grid, maybe I can enter it using the same control. To straight things up here, I’m writing ERP-like system that is using WPF as a view layer. I’m using 3rd party data grid control that is really powerful, so I had all the means. Anyway, at first it seemed like a great idea, but after a while whole lot of challenges appeared. First, if you don’t have a source code to really complex control, and you want use something extraordinary sooner or later you will run into problems. Even with XAML great templating capabilities. Other issues showed up when the number of fields to display arose – it made scrolling and grouping really useless. Eventually I gave up and decided that grids are great for displaying concise pieces of data. Lesson learned.

If you are new to WPF and want to see it’s power I suggest to see this dnrTv video. It shows how boring forms can become something like an art yet having a lot more of usability and productivity. It’s a lot more than fancy flash sites, where everything is pretty, but damn hard to use.

Technorati Tagi: ,

Recently I got very interested in a S#arp Architecture - ASP.NET MVC & nHibernate based architectural foundation. In fact my prolonged 100FeetUnder project is going to use it. For all you who want to create a new ASP.NET MVC project I strongly suggest to consider S#arp option, it looks very promising and it is truly a time saver (of course at first there is a quite steep learning curve, but well, nothing is for free (except the beer ?)).

One example of S#arp based commercial app is FancyDressOutfitters and just a few days ago team that created this site decide to contribute and created a new demo project called Who can help me. This project is currently hosted at CodePlex here and if you got really interested here is a S#arp Architecture google group post about it.

There are times when you have to do something fairly simple that turns out to be quite complicated. Maybe you have to reflect on your code and pull something out - sounds easy. Getting a list of methods or attributes attached to property is straightforward and easy to wrap your mind around. Things can get a little bit more complicated while using reflections to manipulate events. You can easily get their list (type.GetEvents()), add another handler (EventInfo.AddEventHandler()) or remove a handler (EventInfo.RemoveEventHandler()). To get a list of attached delegates you have to do something more.

Our event is more like a syntactic sugar, and under hood is a little bit more complex (more about it you can find on this page in a chapter “A shortcut: field-like events”). In my example I’m looking for all events in an particular class and for each of them I’m adding a simple delegate, but only if this event is empty (has no handlers).

TestEventClass instance = new TestEventClass();
foreach (var e in typeof(TestEventClass).GetEvents())
{
    FieldInfo fi = instance.GetType().GetField(e.Name, BindingFlags.NonPublic | BindingFlags.Instance);
    object value = fi.GetValue(instance);
    if (value == null)
    {
        e.AddEventHandler(instance, (TestDelegate)(delegate() {DoSmthg();}));
    }
}

First step is to look for all events in a class. After that we need to get instance field with a name of particular event (notice that this field is private). Then we just need to take a value of it – it’s our System.MulticastDelegate. This class has a GetInvocationList() method that is returning a Delegate[] array.

 

Technorati Tagi: ,

And I don’t mean data persistence here. More than two years ago I was a member of Imagine Cup team. We were competing in an embedded category, and our subject was IdeoGraph (IdeoGraph Imagine Cup report).  Main part of this system was an IdeoPen, 3D pointing device that was a size of and looked like a real pen. It’s main part were 3 3-axis accelerometers so we were able to collect any data consisting it’s location in 3D space. The idea was great, possibilities were infinite, “sky was a limit”. We made it to the Polish finals, and well, that was all. We were thinking about making it a more mature product, but an overwhelming amount of mundane things took all of our free time and in the end IdeoGraph was forgotten.

ideograph

Then about two years later Sony has shown their new controller. And yes, it’s basically the same idea, I think that even the same technology, but their product was finished, polished and was shown to public. Who knows what would have happened if we were more persistent ? I guess that lesson was learned.

 

When using custom Distinct operator on SQL data source you are going to see “Unsupported overload used for query operator 'Distinct'” exception. Basically it’s because Linq to SQL doesn’t support custom operators. One way to overcome this problem is forcing immediate query evaluation by using for example ToList() method.

Ex. before:

db.SomeTable.Distinct(new CustomComparer())

After:

db.SomeTable.ToList().Distinct(new CustomComparer())

I’m a proud member of PG.NET (Poznan .NET Group). It’s small (usually about 20-30 people per meeting), but very friendly group of smart people, who just want one thing - “to know” :-) Yesterday’s one was rather unusual because it was joined (from SQL point of view it was rather a UNION) with PLSSUG (Polish SQL Server User Group) Poznan user group, or maybe I should say – it was dominated by them, but it turned out to be really interesting (from .NET developer perspective).

First speech was by Gerard Frankowski from PSNC (Poznan Supercomputing and Networking Center) Security Team. It was about Secure usage of MS SQL Server 2008. I must say that I was impressed by knowledge and professionalism of this person. Among rather regular topics like attack types, password strength, Gerard shown us a bug in MS SQL Server 2008. In a shortcut it is possible to read a part of memory occupied by MS SQL process and to see users unencrypted passwords, however you will need administrator privileges to do that. More about this problem here. Gerard has shown us on live demonstration how to take an advantage of this vulnerability, by simply attaching to MS SQL process and reading it’s memory blocks. That actually made my quite nostalgic, every time I see something like this, I’ve a memory recall of me being a kid and hacking through a save files of various games. I guess it was after I’ve just made my gold counter to 999999 in Heroes Of Might And Magic when I had one of this “I’m god of this machine” feelings :-) Who knows, maybe it was that feeling that pushed me to become a software developer ?

Second speech was by Daniel Dudek and it was about SQL Compact Edition and Sync Services. Well, title says it all, Daniel’s presentation was very interesting and quite entertaining. There were little problem’s with live presentation, but as you know, Murphy’s laws are there waiting :-) I’m not going to replicate information about this subjects because you can find everything on Daniel’s blog.

Tags:

There are times when you are about to complete task that is seemingly easy, but somehow you know that you are not doing it right. It’s a feeling that you can get when trying to saw through a wooden beam with a handsaw, while there is a brand new, shiny chainsaw laying nearby. There is only one problem, you have no idea how to use it. And here comes a dilemma, whether to take some time and learn how chainsaw works, or maybe to let it go, and just do it with familiar tool. Learning new equipment is going to take you a lot more time and effort than just quick usage of simpler tool - and there are ominous deadlines. Of course gained knowledge can benefit in a future, when similar task will appear – you chainsaw skill will be ready.

So what to do ? As always there is no good answer… but wait, maybe there is – it depends. But that is a topic for a whole new big article, and we have got some XML waiting.

XSLT – it’s like a giant sawmill for XML, yet it’s light and elegant as handsaw. To understand it deeply you have got to learn your lesson, but fortunately there are useful XSLT snippets flying by, and they might be exactly what you are looking for. And here is my brick in this google an answer move, easy way to copy your XML file, but with sort a node option. So basically we provide an XML file, this XSLT snippet, and as a result we have got same XML file but sorted accordingly to our needs.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
        <xsl:apply-templates select="node()|@*"> 
            <xsl:sort select="author"/> 
        </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet>

Where author is a node by which we want it sorted.

I hope that someone is going to find it useful.

Tags: ,