WPF Reflections


November 27, 2007  4:31 PM

Acropolis – aka MVC

Mark Shurmer Profile: MarkWPF

Let’s go back in time…. Back to the dark ages of IT

Somebody, I’m not sure who, invented a mechanism called MVC [model view controller] and life was good. It did seriously help with the early nightmares in the object orientated world. For most of us, that meant C++ :-)
It separated out the logic for displaying data [view] from the logic for managing data [model/document], and the logic for manipulating both and providing the glue.
It seemed so obvious after using it for the first time that I wondered why we hadn’t used it before!

Now, we have gone through many (many many) hurdles since then. We still have MVC bless it, and guess what it’s still going strong.
It’s essence is as true today as it was 15 years ago (blimey). We still need to separate display logic from data management. What’s changed is that the tools are better (yes, I’m sure, honest), and the mechanisms for achieving the MVC paradigm are different. Also we have much more data, so we need to do it faster.

The latest incarnation happens to be Acropolis, built on top of the WPF framework – it looks good to me, more like a beta than a CTP!

November 23, 2007  3:55 PM

Settings – adding custom class

Mark Shurmer Profile: MarkWPF

Have you ever wondered how you enter custom classes into the new vs2005 (and vs2008) settings editor?
Or like me, desperately tried to do so and couldn’t the information anywhere.

A little information as to what I’m blathering about.
In the VS2005/VS2008 settings editor, you can specify the type of the setting from a drop down list. Also at the bottom you can choose browse to view all types. That has all the assemblies listed that you have referenced as non project references. However it doesn’t have any types listed from your project based references – annoying.

Then by accident I discovered it!

You simply type into the combo box after choosing browse, and lo and behold, it will find your types. You do have to type in your whole namespace as well though.


November 23, 2007  3:33 PM

Items Control – useful tip

Mark Shurmer Profile: MarkWPF

When you are updating the items or the collection pointed to by ItemsSource on an ItemsControl (or ListBox or ListView), do you wish you could SuspendLayout and ResumeLayout, like in Windows Forms days?

Well, you can!

What you need to do is call DeferRefresh, like so:


using(dataView.DeferRefresh())
{
dataView.SortDescriptions.Clear();
dataView.SortDescriptions.Add(new SortDescription(headerProperty, GetLastSortDirection(lv)));
}

here i am going to sort a ListView, but don’t want any layout calculations to occur etc

It will stop any updates happening, then do a Refresh() as you go out of scope of the using statement


November 22, 2007  12:01 PM

Missing controls

Mark Shurmer Profile: MarkWPF

I believe there are a number of missing controls from WPF as of November 2007, despite the RTM of Visual Studio 2008, by comparison with Windows Forms v2.

  • NumericUpDown (aka Spinner) – is a serious omission as it’s not simple to replicate
  • DomainUpDown – is also a serious omission
  • MaskedTextBox – can be replicated relatively easily using the KeyDown event, but it is a bit of a
  • LinkLabel – can be easily replicated by using a hyperlink inside a TextBlock
  • DateTimePicker – another serious omission, as it is a serious undertaking to write
  • MonthCalendar – again, a lengthy process to provide a replacement
  • CheckedListBox – this can be replicated by using a custom item template

How do you get around these problems, well you have a number of options

  1. Write your own versions
  2. Buy in a third party library
  3. Use a freeware libary
  4. Wait for Microsoft to implement

 Of these, option 4 looks like it will be a long wait (but why? why?) as can be seen by how long it took them to provide proper menus and toolbars in winforms.
Option 3 has some appeal, especially since one of the WPF main people Kevin Moore has provided just such an item with NumericUpDown, DateTimePicker and MonthCalendar – but as with all freeware they have problems. To be fair, he provides them as is and as building blocks only.
Option 2 is expensive obviously, and most places I’ve worked are opposed on many grounds (cost, maintenance, red tape)
That leaves option 1, which isn’t what I thought WPF was going to be about


November 15, 2007  3:48 PM

ListView – is it really too slow?

Mark Shurmer Profile: MarkWPF

I have seen a number of blog entries along the lines of ‘ListView is too slow’, or ‘WPF is too slow’, or the worst one of all ‘ListView has performance issues’.
Obviously none of them mention any details, nor elaborate on what issues there might be – sounds a bit like an old project manager of mine :-)

So, what is the reality? That is difficult to know, as there a number of things that can adversely affect the performance of a ListView – but are by no means certain to do so!

Some of the things that may affect performance are:

  • Embedding the ListView inside a StackPanel
  • Embedding the ListView inside a ScrollViewer
  • Not setting ScrollViewer.CanContentScroll to true
  • Having too many columns
  • Having UI Virtualization turned off (VirtualizingStackPanel.IsVirtualizing)

 There may be some more!

To answer the question, is it too slow? As long as you follow the above, then no
 


November 14, 2007  2:03 PM

ListBox – multi column example

Mark Shurmer Profile: MarkWPF

A listbox can easily be used as a multi-column list in WPF. To do that, you need firstly, a listbox:

<Listbox x:Name="lbFields" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=blah}" >

Then, you need to define a couple of templates, one for the headers and one for the items to be drawn. The header one needs to style the buttons that you will use to action header clicking:

<ControlTemplate x:Key="Header" TargetType="{x:Type Button}">
  <Border Background="Silver" TextBlock.Foreground="White" TextBlock.FontSize="10"      Padding="10,3,10,4">
  <ContentPresenter/>
  </Border>
  </ControlTemplate>

Then the template for the items, i’m using a custom object with 4 properties, but it can be anything of course:

<DataTemplate x:Key="readonlyColInfo">
  <Grid ShowGridLines="True" >
  <Grid.ColumnDefinitions>
  <ColumnDefinition Width="Auto" SharedSizeGroup="NameColumn"/>
  <ColumnDefinition Width="Auto" SharedSizeGroup="WidthColumn"/>
  <ColumnDefinition Width="Auto" SharedSizeGroup="AutoFitColumn"/>
  <ColumnDefinition Width="Auto" SharedSizeGroup="VisibleColumn"/>
  </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="10,0,10,0" Text="{Binding Path=Name}"/>
  <TextBlock Grid.Column="1" Margin="10,0,10,0" Text="{Binding Path=Width}"/>
  <TextBlock Grid.Column="2" Margin="10,0,10,0" Text="{Binding Path=AutoFit}"/>
  <TextBlock Grid.Column="3" Margin="10,0,10,0" Text="{Binding Path=Visible}" />
  </Grid>
  </DataTemplate>

Note, we use shared size grouping on the columns, that’s so that the grids containing the headers and the items size the same.
Then we need to apply these templates to the listbox, which we do via a style:

<Style x:Key="{x:Type ListBox}" TargetType="{x:Type ListBox}">
  <Setter Property="Template">
    <Setter.Value>
  <ControlTemplate>
  <Grid>
  <Grid.RowDefinitions>
     <RowDefinition Height="Auto"/>
     <RowDefinition Height="*"/>
  </Grid.RowDefinitions>
<Border Grid.Row="1">
  <Border Margin="10" BorderThickness="1" BorderBrush="Black">
     <DockPanel Grid.IsSharedSizeScope="True">
        <ScrollViewer HorizontalScrollBarVisibility="Hidden"             VerticalScrollBarVisibility="Auto"             DockPanel.Dock="Top">
  <Grid DockPanel.Dock="Top" Margin="0,0,18,0">
     <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" SharedSizeGroup="NameColumn"/>
      <ColumnDefinition Width="Auto" SharedSizeGroup="WidthColumn"/>
      <ColumnDefinition Width="Auto" SharedSizeGroup="AutoFitColumn"/>
      <ColumnDefinition Width="Auto" SharedSizeGroup="VisibleColumn"/>
    </Grid.ColumnDefinitions>
    <Button Grid.Column="0" Template="{StaticResource Header}"> Name </Button>
    <Button Grid.Column="1" Template="{StaticResource Header}" > Width </Button>
    <Button Grid.Column="2" Template="{StaticResource Header}" > Auto fit </Button>
    <Button Grid.Column="3" Template="{StaticResource Header}"> Visible </Button>
  </Grid>
  </ScrollViewer>
  <ScrollViewer HorizontalScrollBarVisibility="Visible" Name="Master">
  <StackPanel IsItemsHost="True"/>
  </ScrollViewer>
  </DockPanel>
  </Border>
  </Border>
  </Grid>
  </ControlTemplate>
  </Setter.Value>
  </Setter>
  </Style>


November 12, 2007  3:05 PM

ListBox – the forgotten control

Mark Shurmer Profile: MarkWPF

How did that happen?

I personally think it happened because when we were all looking at WPF to begin with (in CTP days), it was very obvious that there was no Grid.
Then, because of that people noticed that the ListView control had the option to specify a grid version as one of it’s views. That wasn’t so different to Win32 or WinForms, but because of the power of WPF it has been easy to adapt to what we all need.

However, in doing so, we have forgotten about the humble old listbox. As I have re-discovered recently, it is very easy to have multi-column listboxes in WPF.
Therefore when I don’t want to be able to switch views (to icon views etc), but just show Line Of Business style multi-column lists I just might use the ListBox instead. As a warning note, you do lose the ability to generate columns , i.e. you have to do it yourself, but it is really very easy

:-)


November 9, 2007  11:04 AM

Acropolis – sections

Mark Shurmer Profile: MarkWPF

There are a number of different elements to an Acropolis application, and they are:

part view
What you see! The user interface portion, and they are sometimes referred to as skins. In the MVC world they were called views.
part
In the MVC world, this would equate to a model. This holds the functionality and data for the part view. Therefore this would hold the logic and state. They separate the implementation of their logic and state from their user interface (view).
child part
A part can be composed of a number of child parts, mainly to allow functionality to be shared.
form
A part that contains one or more child parts that work together to implement a specific function, scenario, or task that the end-user can perform. A form can implement a specific navigational pattern to help the user to accomplish the task that it implements. You can nest Acropolis forms to provide rich user interface structures.
service
An application-level capability that implements a specific strategy or provides pluggable functionality, such as logging, event routing, and so on. These can be applied across different parts of course, so provide shared functinality, as well as supplementing their own business logic. They can be customised as well.
connection point
A point of communication between a part and other Acropolis components, such as the part’s view, other parts, or services. Connection points come in multiple types including ComponentProperty, ComponentCommand, ComponentNotification, and ServiceDependency.

More soon…


November 9, 2007  9:23 AM

Drag and drop – checking mouse button

Mark Shurmer Profile: MarkWPF

If you are doing drag and drop by hand (rather than using Josh Smith’s excellent DragAndDropManager – http://www.codeproject.com/WPF/ListViewDragDropManager.asp) for whatever reason, one thing to be careful is to to allow existing functionality to carry on working.

For example, in a listview, you want the ability to drag and drop column headers (to move columns around) to continue, if it has been turned on by setting AllowsColumnReorder=”True”.
Therefore you need to check that when the left mouse button is pressed, you only specify it as a drag and drop button click if you are sure it’s a listviewitem being selected, rather than a scrollbar or a header.
You could  walk up the visual tree looking for the right type of control, or look for a property being set somewhere in the visual tree. However, what I have found useful is to check that the originating element’s datacontext is set to the type of the listviewitem’s bound type. This only works if you’re using databinding and an itemscontrol or descendent (listbox or listview), but is quick and easy :-)

An example:

private void lv_PreviewMouseLeftButtonDown(object sender, MouseEventArgs e)
{
// check to see if drag can be done
FrameworkElement ele = e.OriginalSource as FrameworkElement;
if(ele != null && ele.DataContext != null && ele.DataContext.GetType() == typeof(xxx))
{
m_StartPoint = e.GetPosition(null); // save mouse position
m_IsDragging = false;
}
else
m_IsDragging = true;
}

where m_IsDragging is a boolean indicating whether you can do drag and drop operation, and m_StartPoint is used by the drag and drop operation to test whether to start doing it, and xxx is your object that is bound to the listview


November 5, 2007  12:05 PM

Acropolis

Mark Shurmer Profile: MarkWPF

Acropolis is the WPF answer to CAB and Smart clients, and more

First off, it should be mentioned that it is a code name, and very much alpha as at November 2007.

What does it do?

  1. Well it sits on top of WPF, and enables the building of smart clients (for a definition of a smart client, see http://en.wikipedia.org/wiki/Smart_client)
  2. You can create MDI applications with it
  3. It provides the plumbing for the applications you want to write, without you having to do it yourself
  4. There are numerous extension points, as well as the opportunity to subclass existing functionality
  5. It has a designer in Visual Studio (2008 of course)


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: