Styling Listbox items with DataTemplate and VisualBrush

I have a simple object with three string fields. I put instances of the object into an ObservableCollection to databind to three listboxes (each field in one box).

My data templates look like this:

<DataTemplate x:Key="FieldATemplate">

<Canvas Width="60" Height="70">

<Border BorderBrush="Black" BorderThickness="2">

<TextBlock Text="{Binding Path=FieldA}" />

</Border>

</Canvas>

</DataTemplate>

<DataTemplate x:Key="FieldBTemplate">

<Ellipse Width="50" Height="50">

<Ellipse.Fill>

<VisualBrush>

<VisualBrush.Visual>

<TextBlock Background="Yellow">

<TextBlock.Text>

<Binding Path="FieldA"></Binding>

</TextBlock.Text>

</TextBlock>

</VisualBrush.Visual>

</VisualBrush>

</Ellipse.Fill>

<Ellipse.Stroke>

<SolidColorBrush Color="Black">

</SolidColorBrush>

</Ellipse.Stroke>

</Ellipse>

</DataTemplate>

The listboxes look like this:

<ListBox ItemTemplate="{DynamicResource FieldATemplate}" ItemsSource="{Binding }">

</ListBox>

<ListBox ItemTemplate="{DynamicResource FieldBTemplate}" ItemsSource="{Binding }">

</ListBox>

The problem is that FieldBTemplate doesn't work. At runtime this is the error I get:

BindingExpression path error: Cannot find property 'FieldA' on object 'null'.

BindingExpression:Path='FieldA'; DataItem='null';

target element is 'TextBlock' (Name=''); target property is 'Text' (type String);

What's wrong Is it a bug in Avalon A limitation of VisualBrush Do I need to add another binding somewhere in the FieldBTemplate I purposely used FieldA in the FieldBTemplate to show that it's not a problem with the object itself.

Regards,

Oluf



Answer this question

Styling Listbox items with DataTemplate and VisualBrush

  • Sstrain

    This is a limitation of all brushes and, more generally, all objects inheriting from Freezable. In the latest available release, you cannot bind data to properties of Freezables.

    "But wait," you say, "I'm not binding a property of a Freezable, I'm binding a property of TextBlock, which inherits from FrameworkElement!" Yes, this is true. However, since you placed the TextBlock inside a VisualBrush the data binding system has to "go through" a Freezable (the brush) to find the data context (the templated item), so the example breaks down.

    In a future release you will be able to do what you are trying to do here with data binding. For now, you have to avoid using a VisualBrush to hold any elements that you want to data-bind. For the time being, for the particular example above you may be able to achieve the visual effect that you are looking for by using an EllipseGeometry as a clip to the TextBox, rather than using the TextBox as a brush to fill an Ellipse.

  • Hans Verkoijen

    Thank you. I thought I was going crazy. Hope to see a release where this works soon.


  • Styling Listbox items with DataTemplate and VisualBrush