Quantcast
Channel: Dev102.com » List
Viewing all articles
Browse latest Browse all 10

Don’t Use a WPF Control in Windows.Resource

$
0
0

Hi

 

Here is a problem that one of my colleagues who is just starting to use WPF got himself into. He was working on an application that displays items using an ItemsControl and uses a DataTemplate. Inside the DataTemplate he used an Image. Here is the Xaml code:

 

   1: <Window.Resources>
   2:         <Image Source="Creek.jpg" x:Key="IMG"></Image>
   3:     </Window.Resources>
   4:     <Grid>
   5:         <ItemsControl ItemsSource="{Binding}">
   6:             <ItemsControl.ItemTemplate>
   7:                 <DataTemplate>
   8:                     <Border BorderThickness="2" BorderBrush="Black" 
   9:                             CornerRadius="3" MinHeight="10">
  10:                         <ContentControl Content="{StaticResource IMG}"/>
  11:                     </Border>
  12:                 </DataTemplate>
  13:             </ItemsControl.ItemTemplate>
  14:         </ItemsControl>
  15:     </Grid>

This is a much simpler example, but the principal is the same.

 

Can you see what was he doing wrong?

 

In the code behind I will create a list and use it as the DataContext:

   1: public Window1()
   2: {
   3:    InitializeComponent();
   4:    List<int> data = new List<int> { 1, 2, 3, 4 };
   5:    this.DataContext = data;
   6: }

You will expect to see a window with 4 Images, but this is what you get:

Bad Resource Usage

Only one image shows up and all the other templates are empty.

 

Can you see the problem now?

 

It took me some time to see it because the code was much more complex, but then I noticed that he used the Image class as a resource for the Image.

 

Image is a WPF Control and can only have one parent! This is why it only displayed at the last item of the list. This is similar to doing the following:

   1: Image m = new Image();
   2: Border b1 = new Border();
   3: Border b2 = new Border();
   4: b1.Child = m;
   5: b2.Child = m;

What would happen here? The following:

Illegal child exception

I was actually surprised that my friend did not get an Exception, I will definitely have to check why no exception was thrown.

To correct the problem all you have to do is to use Bitmap Image which is a C# Class and not a WPF Control. You should use an Image in the template and use the BitmapImage as its source:

   1: <Window.Resources>
   2:    <!--<Image Source="Creek.jpg" x:Key="IMG"></Image>-->
   3:    <BitmapImage UriSource="Creek.jpg" x:Key="BMP"></BitmapImage>
   4: </Window.Resources>    
   5: <Grid>
   6:    <ItemsControl ItemsSource="{Binding}">
   7:        <ItemsControl.ItemTemplate>
   8:            <DataTemplate>
   9:                <Border BorderThickness="2" BorderBrush="Black" 
  10:                        CornerRadius="3" MinHeight="10">
  11:                    <!--<ContentControl Content="{StaticResource IMG}"/>-->
  12:                    <Image Source="{StaticResource BMP}"></Image>
  13:                </Border>
  14:            </DataTemplate>
  15:        </ItemsControl.ItemTemplate>
  16:    </ItemsControl>
  17: </Grid>

The result:

Good Resource Usage

 

Exactly what we wanted.

 

If any of you have an idea as to why we did not get an exception I will be happy to hear it.

 

Amit


Copyright © 2008
This feed is for personal, non-commercial use only.
The use of this feed on other websites breaches copyright. If this content is not in your news reader, it makes the page you are viewing an infringement of the copyright. (Digital Fingerprint:
)

Viewing all articles
Browse latest Browse all 10

Latest Images

Trending Articles





Latest Images