Tuesday, August 08, 2006

An article has just been published on code project by Josh Smith that should not escape your attention: Piping value converters in WPF.

Basically, he has written a simple class that will allow you to define a group of converters and use it during databinding like so:
    <local:ValueConverterGroup x:Key="statusForegroundGroup">
      <local:IntegerStringToProcessingStateConverter  />
      <local:ProcessingStateToColorConverter />
      <local:ColorToSolidColorBrushConverter />
    </local:
ValueConverterGroup>

and then use it like so:

        <TextBlock
          Text="{Binding XPath=@Status,
                 Converter={StaticResource statusDisplayNameGroup}}"

          Foreground="{Binding XPath=@Status,
                       Converter={StaticResource statusForegroundGroup}}"
/>

This should prove very valuable indeed!

Tuesday, August 08, 2006 8:46:39 AM (Romance Standard Time, UTC+01:00)  #    Comments [1]  |  Trackback
 Monday, July 31, 2006

A small tip today on how to access elements that are embedded within a control template. In my case for an itemscontrol class.
Consider the following Xaml:

<ItemsControl

    x:Class="Client.Framework.TijdslijnVisualizer.TijdslijnVisualisatie"

    xmlns:cf="clr-namespace:Client.Framework.TijdslijnVisualizer"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    >

  <ItemsControl.Style>

    <Style TargetType="{x:Type ItemsControl}">

      <Setter Property="Template">

        <Setter.Value>

          <ControlTemplate TargetType="{x:Type ItemsControl}">

            <DockPanel LastChildFill="True">

              <Slider Name="slider" DockPanel.Dock="Right" Minimum="1" Maximum="10" Value="1" Orientation="Vertical" />

              <ScrollViewer Name="scroller" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="False">

                <cf:TijdslijnPanel Name="tijdslijnpanel"  IsItemsHost="True" zoomFactor="{Binding ElementName=slider, Path=Value }" />

              </ScrollViewer>

            </DockPanel>

          </ControlTemplate>

        </Setter.Value>

      </Setter>

    </Style>

  </ItemsControl.Style>

</ItemsControl>

 

In the code behind for this class you will not be able to simply get the to these elements with ease. Or at least, not until I realized that these elements were not set yet until the template was actually applied. If you try to find them after that, you will find them through the VisualTreeHelper.GetChild or a simple .FindName:

 

        public override void OnApplyTemplate()

        {

            base.OnApplyTemplate();

 

            this.slider = (Slider) this.Template.FindName("slider", this);

            this.scroller = (ScrollViewer) this.Template.FindName("scroller", this);

 

            // other stuff

        }

 

I hope this helps somebody out there!

 

Monday, July 31, 2006 2:46:33 PM (Romance Standard Time, UTC+01:00)  #    Comments [5]  |  Trackback
 Friday, July 28, 2006

Just a little tip, showcasing the power of Xaml and the efficiency of good code/design separation.

When you are fetching data from a server, you could (and actually should) use the DataModel-View-ViewModel pattern, as described by Dan Crevier from the Microsoft Max team. It uses a viewmodel-class to bind your Xaml against. Dan then implements a 'state' property to indicate whether the model is finished fetching and is in a 'bindable' state.

If you are short on time, or have other reasons not to implement such a strategy, you are probably binding straight to objects that are still Null during the fetch-action.
In either case, it would be nice to let the user know that data is being fetched.

In my case, I had a lot of <TabItem>'s that are being filled with data, one-by-one, by setting the datacontext directly. While designing the user interface, I do not want to have to think about the possibility of binding against an invalid object (it being null). So I created a style, that I put in the application resources. The style replaces my content-template with a temporary template, whilst in invalid state. I was extremely satisfied with the solution, because it was so dead-easy, and it works like a charm.

Here is the code (don't mock my visually stunning border please ;-) ):

    <Style BasedOn="{StaticResource {x:Type TabItem}}" TargetType="{x:Type TabItem}">

      <Style.Triggers>

        <Trigger Property="DataContext" Value="{x:Null}">

          <Setter Property="ContentTemplate">

            <Setter.Value>

              <DataTemplate>

                <Border CornerRadius="5" BorderThickness="2" BorderBrush="Black" Background="Yellow" Height="60" Width="280"

                        HorizontalAlignment="Center" VerticalAlignment="Center">

                  <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Data is being fetched</TextBlock>

                </Border>

              </DataTemplate>

            </Setter.Value>

          </Setter>

        </Trigger>

      </Style.Triggers>

    </Style>

I was pleasantly surprised by the simplicity of the code. The DataContext is used in a trigger to set the content-template.

Friday, July 28, 2006 2:48:29 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback
 Wednesday, July 26, 2006

Microsoft apparently had reasons not shipping WPF with a datepicker control. In my opinion such a control is of great importance when you are building applications. How can I sell a platform to a client when I have to explain that they won't be able to visually enter a date? (Or have to hire me to build such a control for them ;-) )
Some time ago I started a forum thread about this issue and the ATC Avalon responded by taking up the challenge and started working on a control. Why that team was dismissed is beyond me, but Kevin Moore finished where they left off. He has posted an update to his bag-of-tricks for the July CTP (they also work on the June CTP), and has included the datepicker sample!

I've quickly checked it out and it's looking great! I wish I could use empty dates though, but that should be easy to hack in.
Thanks Kevin!

Wednesday, July 26, 2006 9:42:24 AM (Romance Standard Time, UTC+01:00)  #    Comments [4]  |  Trackback