views:

215

answers:

1

I am using Expression Blend 4 and Visual Studio 2010 to create a Sketchflow prototype.

I have a Sample Data collection and a ListBox that is bound to it. This displays as I would expect both at design time and at run time. However, the ListBoxItem template it just complex enough that I wanted to pull it out into its own XAML file. Even though the items still render as expected in the main ListBox where the template is used, when I open the template itself, all of the databound controls are empty.

If I add a DataContext to the template, I can see and work with the populated objects while in the template, but then that local DataContext overrides the DataContext set on the listbox.

A bit of code will illustrate. Start by creating a Sketchflow project (I am using Silverlight, but it should work the same for WPF), then add a project data source called SampleDataSource. Add a collection called ListData, with a single String property called Title.

Here is the (scaled down) code for the main Sketchflow screen, which we'll call Main.xaml:

<UserControl
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:local="clr-namespace:DemoScreens"
 mc:Ignorable="d"
 x:Class="DemoScreens.Main"
 Width="800" Height="600">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="ProjectDataSources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <DataTemplate x:Key="ListBoxItemTemplate">
             <local:DemoListBoxItemTemplate d:IsPrototypingComposition="True"     Margin="0,0,5,0" Width="748"/>
            </DataTemplate>
        </ResourceDictionary>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="#5c87b2" DataContext="{Binding Source={StaticResource SampleDataSource}}">
          <ListBox Background="White" x:Name="DemoList" Style="{StaticResource ListBox-Sketch}" Margin="20,100,20,20" ItemTemplate="{StaticResource ListBoxItemTemplate}" ItemsSource="{Binding ListData}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"/>
    </Grid>
</UserControl>

You can see that it references the DemoListBoxItemTemplate, which is defined in its own DemoListBoxItemTemplate.xaml:

<UserControl
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:local="clr-namespace:DemoScreens"
 mc:Ignorable="d"
 x:Class="DemoScreens.DemoListBoxItemTemplate">
 <Grid x:Name="LayoutRoot">
  <TextBlock Text="{Binding Title}" Style="{StaticResource BasicTextBlock-Sketch}" Width="150"/>
    </Grid>
</UserControl>

Obviously, this is way simpler than my actual listbox, but it should be enough to illustrate my problem. When you open Main.xaml in the Expression designer, the list box is populated with sample data. But when you open DemoListBoxItemTemplate.xaml, there is no data context and therefore no data to display—which makes it more difficult to identify controls visually.

How can I have sample data displayed when I am working with the template, while still allowing the larger set of sample data to be used for the ListBox itself?

A: 

I believe this should work for you, I just tried it with SL and Blend 4:

  1. Instead of making your template into a usercontrol to put it into a separate file, move the template into its own resource dictionary.
  2. To add a new resource dictionary, there is a button in the upper right of the resources panel.
  3. Find the template (might be named ItemTemplate by default) in the resources of your usercontrol, right click it to copy, paste it into the new resource dictionary.
  4. Delete the original resource, this will likely give you a warning about references, if you leave them the same they may still work because the names will be the same, if not:
  5. Right click your listbox, edit additional templates, items template, apply resource and pick the ItemTemplate from your new resource dictionary.

Now your template is in a separate file, and should still be editable with a datacontext, although it will not be in place on the artboard like it is if the data template is in the same usercontrol.

Hope that helps, let me know if it doesn't.

Chuck Hays
Thanks, I tried this suggestion, but I ended up with a very similar result: any datacontext I set on the resource (so that I can see at design time how the contents lay out) overrides the datacontext set for the list box (which I want to see at runtime).I do appreciate the thorough reply, though!
Boris Nikolaevich
You shouldn't need a separate datacontext for the resource, it should inherit the one from where it is being edited.
Chuck Hays