Taoffi's blog

prisonniers du temps

Choices in a logical tree view – WPF sample

Using check boxes in TreeView control is a handy way for presenting choices in their logical tree-like structure.

In real life, though, choices can be a mix of inclusive (check-box) and exclusive (radio-button) options.

I expose here a solution for using that mix of option types in one same tree view.

The problem

The problem is divided into three main subjects:

  • How to use a mix of checkbox / radio button nodes in the same tree view control
  • How to get a radio button to be toggled from checked to unchecked status: Checkboxes are, 'naturally', able to be toggled from checked to unchecked status. This is not the case for Radio buttons. The result is that when you use radio button in a tree view, you will be able to check it but not to get it uncheck!
  • How to handle exclusive choices selection. That is when an exclusive option gets selected (checked), for instance,we must unselect all other exclusive sibling options.

 

To solve the first question, we will use:

  • A tree node object which indicates its option type (exclusive / inclusive)
  • Hierarchical control templates for each choice type
  • A template selector which will select the correct template according to the node object choice type

 

To solve the second, we will simply create a new Toggled Radio Button (which derives from RadioButton) and get this new object handle the Click event to toggle its selection status.

 

 

public class RadioToggleButton : RadioButton
{
    protected override void OnClick()
    {
        IsChecked = !IsChecked;
    }
}

 

 

The third question will be solved by implementing the required behaviors within our special tree node object.

 

The TreeNode object

The TreeNode object exposes few properties:

  • A Title
  • A Parent node (TreeNode)
  • A list of Children (List of TreeNode items)
  • A boolean flag which indicates if the node represents an exclusive choice option
  • A boolean flag which indicates if the node is selected

Through these properties, TreeNode object can expose other properties like its Root node, the First exclusive parent or descendant… etc.

 

The TreeNode Hierarchical data template

 

<UserControl.Resources>
…
…
    <!-- hierarchical template for checkbox treeview items -->
    <HierarchicalDataTemplate x:Key="checkBoxTemplate" 
        DataType="{x:Type app:TreeNode}"
        ItemsSource="{Binding Children}">
        <StackPanel Orientation="Horizontal">
            <CheckBox Focusable="False"
                VerticalAlignment="Center"
                IsChecked="{Binding IsSelected, Mode=TwoWay}" />
            <TextBlock Text="{Binding Title}" />
        </StackPanel>
    </HierarchicalDataTemplate>
 
    <!-- hierarchical template for (toggled) radio buttons treeview items -->
    <HierarchicalDataTemplate x:Key="radioButtonTemplate" 
            DataType="{x:Type app:TreeNode}"
            ItemsSource="{Binding Children}">
        <StackPanel Orientation="Horizontal">
            <ctrl:RadioToggleButton Focusable="False"
            VerticalAlignment="Center"
            IsChecked="{Binding IsSelected, Mode=TwoWay}" />
            <TextBlock Text="{Binding Title}" Margin="4, 1, 0, 0" />
        </StackPanel>
    </HierarchicalDataTemplate>
</UserControl.Resources>

 

 

The TreeView node's Item template selector

 

public class TreeNodeXTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(
                object item, DependencyObject container)
    {
        FrameworkElement    element = container    as FrameworkElement;
        TreeNode    node    = item  as TreeNode;
 
        if (element != null && node != null)
        {
            if (node.IsExclusive)
                return element.FindResource("radioButtonTemplate")
                                 as HierarchicalDataTemplate;
            return element.FindResource("checkBoxTemplate")
                                as HierarchicalDataTemplate;
        }
        return null;
    }
}

 

 

We can now use an ItemTemplateSelector to tell the Tree view control to select the adequate data template for each item according the tree node choice selection type (exclusive / inclusive)

 

<UserControl.Resources>
    <app:TreeNodeXTemplateSelector	x:Key="templateSelector" />
    …
    …
</UserControl.Resources>

 

<TreeView x:Name="treeview1" ItemsSource="{Binding Root.Children}"
                  ItemTemplateSelector="{StaticResource templateSelector}"/>

 

 

Exclusive node selection behavior

TreeNode selection behavior can be summarized as follows:

  • If the node is inclusive: do nothing (just set the selected flag)
  • If the node is exclusive (and selected):
    • Unselect all exclusive siblings (siblings = Parent's Children)
    • Select all inclusive child nodes
    • Select the first exclusive child node if any

 

public void UpdateSelection()
{
    if(! _isExclusive)
        return;
 
    if(_isSelected == true)
    {
        UnSelectSiblings();
    }
 
    SelectChildren(_isSelected);
}

 

 

 

protected void SelectChildren(bool selected)
{
    if(! selected)
    {
        UnSelectChildren();
        return;
    }
 
    TreeNode firstEx = FirstExclusiveChild;
 
    if(firstEx != null)
        firstEx.IsSelected = selected;
 
    foreach(TreeNode node in _children)
    {
        if(node.IsExclusive)
            continue;
 
        node.SetSelection(value: selected, updateChildren: true);
    }
}

 

 

Sample screenshot

 

Download the sample code TreeViewRadioAndCheckButtons.zip (67.88 kb)

Microsoft case: going monochrome

On the Windows Phone 8, the latest MSFT phone OS, you have a nice Theme selection option, which says:

"Change your phone's background and accent color to suit your mood today, this week or all month"

Quite attractive!

The feature proposes two settings:

  • Background
  • Accent color

 

On 'Background', you have two options: Light / Dark

On 'Accent color', you have a palette of 21 colors (which seems to be a pretty little choice on a device that, according to the manufacturer, can display 65000 colors or more!)

I should admit, that not having a choice is in a way less time consuming. May be this was the initial OS designer's intended objective.

 

Now let us leave WP and go back to the desktop machine to have a look at Microsoft Office 2013.

Here too, you have a nice feature to select your theme.

You have the choice between:

  • White
  • Light gray
  • Dark grey

 

The difference between the three is really too subtle:

I tried them all, and ended up by selecting 'Dark': a little more readable!

On another point: after all the literature about the 'user interface design guidelines', it now seems that Microsoft Office apps are the only applications that can keep being outside of any graphical constraints. Those guys are really too spoiledJ

 

Conclusion

It seems that someone at MSFT has decided to re-form our education about colors. The 'monochrome' seems to be the new MSFT User Interface Strategy (you can check yourself: Windows Phone, Windows 8, Office 2013…)

Some people may find this abusive… but, in a way, we are much less embarrassed with this new reduced theme strategy… we may gain more time to think about things more useful!

Of recipes and methods – Agile and agile rituals

Let me first clarify:

Learning that the square root of 144 = 12 is a 'recipe'.

Learning how to retrieve the square root of a number is a 'method'.

Recipes represent one application of a method in a specific context.

They are efficient and straightforward, gratifying, easier to retain and easier to sell !

Still they most likely apply to a context and can hardly be useful if elements of the context change.

Methods are less easy to retain and assimilate. They also often need to be ascertained through applications in various contexts before being accepted.

The bad thing with recipes is that they are sealed, and tend sometimes to occult the openness of their originating method.

One good demonstrative example of this is the Agile principles (method) vs. the multitude of – more or less ridiculous – rituals (recipes) falsely attributed to the originating method.

Some of the rituals may have been correctly applied in specific contexts producing suitable results. But, no doubt, with different context, the same 'successful' rituals may be disastrous.

It is easier to retain rituals than to understand principles… even easier to retain those rituals that you may find attractive!

Meta-models: towards a universal dependency injection framework

Intro

I joined an interesting presentation today about unit tests. Part of the presentation was related to dependency injection usage for unit testing. That brought to my mind again the benefits of meta-models.

The problem

Unit testing often faces the problem of having to instantiate objects that may impact the test itself or simply make the test impossible.

A sound example of this is when the method to be tested requires the instantiation of an object requiring, for instance, a database connection.

In this schema, we have 3 actors

  • The function
  • The caller
  • The object (SomeObject) which cannot be instantiated.

 

Traditional recipe

One, now traditional, recipe is to use an Interface (instead of the specific object) as a function parameter. And, according to the context, instantiate and use an object that implements the defined interface. The figure below illustrates this.

 

Good solution… a little acrobatic, but OK… good.

 

A problem, though. We now have 6 actors (to code and maintain):

  • The Function
  • The caller
  • The original 'true' object (SomeObject)
  • The Interface
  • The interface implementations (=2)!

 

On the other hand, testing a function may also need to instantiate a 'true' object context. In which case, we would have to rewrite (and recompileJ) our test code to instantiate a 'true' implementation when required.

A third point: in this solution, we defined the Interface to represent an abstraction of the original object. What if the original object itself was, for instance, a database record? This would then introduce a new actor in our playgroundJ

 

As Bjarne Stroustrup puts it:

"Any verbose and tedious solution is error-prone because programmers get bored" J

 

Meta-models may be a better way

In the current case, meta-models (see my previous posts) can be used to more simply describe all actors (object structures / methods / properties…).

An illustration:

 

 

Reminder: meta-models are closely related and enforced by Reflection (assemblies' meta-data). Through meta-models AND Reflection (namespace System.Reflection) developers can gain more flexibility to create versatile and scalable software.

 

In our present case, meta-models not only expose less actors to code and maintain, but also lower the complexity level of involved actors (for instance: maintaining database records instead of hard coding implementation).

 

The main goal for this approach is to ultimately write fewer universal methods to invoke and instantiate any object!

Will try to deliver a code sample in a future post. In the meantime, you may download meta-model sample code here!

TFS & SQL Server 2008R2 msxmlsql issues

I recently went through another new issue with TFS:

I had the TFS database and Data warehouse both installed on a SQL Server 2008 instance.

After installing a new SQL Server 2008R2 instance, TFS just stopped working complaining about database access.

It took me a while to re-discover that the source of annoyance was – again - the msxmlsql.dll and msxmlsql.rll files located at:

\Program Files\Microsoft SQL Server\100\Shared

And

\Program Files\Microsoft SQL Server\100\Shared\Resources\1033

respectively.

 

For some reason (seems useless to spend time searching J) the versions to use are with TFS are:

msxmlsql.dll (1,311,256 bytes); 07/10/2008; file version: 2007.100.1600.22

msxmlsql.rll (52 248 bytes); 07/10/2008

 

The files that caused my problem:

msxmlsql.dll (1 308 000 bytes bytes); 04/03/2010; file version: 2009.100.1600.1

msxmlsql.rll (48 992 bytes); 04/03/2010

 

 

 

 

MOD: Mur Oriented Development

MOD est un pattern connu de gestion de projets. Il s'agit de réussir son entrée dans le mur !

Sa pratique est assez simple : elle consiste justement à éviter, au dernier moment, de rentrer dans le mur. Adopter MOD est facile. Le maîtriser et le réussir est une autre affaire !

Champollion: 20 months and 20 days in ancient Egypt

 

Jean-François Champollion who made the first translation of the ancient hieroglyph (in 1822-1824, before ever going to Egypt) made his first (and last) journey to Egypt in 1828-1829. He spent 20 months and 20 days in this journey (of which the last 60 days in quarantine in Toulon when he was back homeJ).

An amazing book "Lettres écrites d'Égypte et de Nubie en 1828 et 1829 by Jean-François Champollion" (there should be an English translation… don't really know) contains a collection of letters - written to his friends, family and some officials- that recount this journey in a very smooth and pedagogic way. In an annex, the book contains a very dense description of the History of ancient Egypt and neighboring civilizations.

Champollion was evidently passionate about ancient Egypt. During this journey, he seems to be revisiting places and events that he knew quite well. And he recounts all of this in a fascinating way.

One thing that may seem a little strange for us, is the time spent in travelling. For instance: it took him several months to travel from Paris to Luxor (in the south of Egypt)… which really seems too long now (probably unacceptable!).

In the same time, he could compose (with his small team), in less than 2 months, more than 600 entire exact colorful drawing copies of all the monuments he visited (including endless hieroglyphic texts!). All in quite harsh travelling conditions between the Nile cataracts.

Near the end of his journey, he heard that Jerusalem's Archbishop decided to honor him with a distinguished prize (Croix de chevalier du saint-sépulcure). He recounts that getting hold of the prize was too expensive for him (200 Louis)!

The book is also available in an audio version (in French) on the great Free Litérature audio web site.

(Not sure you can write code while hearing such a bookJ)

SQL Replication: Windows Sync Manager and orphaned subscriptions

It is quite useful and handy to synchronize SQL replicated databases through the Windows Synchronization Manager. You simply click the Sync Manager / Click Microsoft SQL Server / Right-click the desired subscription to synchronize and click Sync. Easy and great!

 

Annoying problems appear in some particular cases. I encountered one of these cases when I had an orphaned subscription (i.e. a subscription that doesn't have any more a declared publication). This may happen when, for instance, the publisher server doesn't exist anymore… or when the publication had been deleted in some circumstances.

The annoyance is that in this case, Windows Sync Manager continues to display the orphaned subscription and you have no means to delete it as this requires contacting the publisher which may not exist anymore and/or deleting the subscription from a publication which may not exist either!.

At this phase, you indeed have little choices… the most reasonable would be to leave this orphaned subscription displayed and simply ignore it (though a little frustratingJ)… That was what I did until I found some time to dig through (little information, if any, is available on this):

 

I ended up by finding that Windows Synchronization Manager reads the list of its displayed subscriptions in the registry key:

HKLM\Software\Microsoft\Microsoft SQL Server\MSSQL10.INSTANCE\Replication\Subscriptions

(MSSQL10.INSTANCE is the SQL version and instance of the subscriber server… which, in the figure below, is MSSQL10.SQL2008).

The subscriptions node contains one key per subscription with required synchronization settings.

 

I simply deleted the key related to the orphaned subscription. To avoid Windows mysteries, I also restarted the machineJ. That now works as I would like. (Craftsmanship again!)

Internet Explorer add-ons: manage allowed sites

Browsers add-ons and plug-ins are nice features that can sometimes become annoying. Flash Player, for instance, is nice but extensively used in boring commercial ads.

Fortunately you can either disable the annoying add-on or allow it to run only on specific sites.

To do this in Internet Explorer:

  • First click Internet options / Programs / Manage add-ons.
  • Select the add-on and click More Information.
  • By default, the add-on is allowed to run on all sites. This is displayed as * (asterisk). Click Remove all sites.
  • Click OK to confirm your choice and close the Internet options dialog. You are done.
  • Now, the add-on will no more be executed on any web site.
  • In fact, each time a web site needs to run the add-on, IE will ask you if you want to allow it to run on this specific site.
  • The list of allowed web sites is then maintained by Internet explorer.

 

 

After some weeks / months / years… this list may become quite long.

Now, what to do to remove just ONE site or TWO of this allowed list?

Internet Explorer allows you to REMOVE ALL SITES… There is no button to remove just ONE site!

So, you remove all sites and start a new history again… More annoying than letting the add-on run on all sites… isn't it?

 

WHERE does IE keep this list? Mystery!

 

After a lot of search, I didn't find any information. Until….

Yes… it is in the registry (Please be extremely cautious when modifying this vital thing: The registry)

 

HKey_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Ext\Stats\[add-on class ID]\iexplore\AllowedDomains

 

Example for Flash Player add-on:

When all sites are allowed:

When only some are:

 

Now, if we want to delete just ONE web site, simply delete its key.

Again: Please be extremely cautious when modifying this vital thing: The registry