Using Wpf RelativeSource Binding breaks Blendability

560 Views Asked by At

I've got the following scenario... I have a Window that contains an ItemsControl. I specify a ViewModel for the Window's DataContext. I specify a DataTemplate for the ItemControl's ItemTemplate. In the the DataTemplate I use a ComboBox and for the ComboBox's ItemsSource I use a RelativeSource Binding to its containing Window's DataContext. During Run-Time everything works fine and the Binding is resolved correctly, but during Design-Time Cider can't pick up the containing Window's ViewModel to which the ItemSource is binding.

Here is my code (I left out the xml namespace declarations at the top, but in my code they are included):

<Window d:DataContext="{Binding Source={StaticResource DesignViewModel}}">

<Window.Resources>
    <designviewmodels:GenresEditorDesignViewModel x:Key="DesignViewModel" />
</Window.Resources>

<ItemsControl Grid.Row="0"  Margin="3" ItemsSource="{Binding Path=CurrentState}" >
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Grid DataContext="{Binding}">
            <Grid.ColumnDefinitions>
               <ColumnDefinition Width="*"></ColumnDefinition>
               <ColumnDefinition Width="20"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <ComboBox Grid.Column="0" Margin="3,0,3,0" 
                ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,  
                AncestorType={x:Type Window}}, Path=DataContext.AvailableGenres, 
                Mode=OneWay}"
                DisplayMemberPath="Name" 
                SelectedItem="{Binding Path=Genre, Mode=TwoWay}" DataContext=" 
                {Binding}" />

                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

So basically from the above piece of code the Path=DataContext.AvailableGenres can not be resolved during Design Time, but during Run Time it is resolved correctly.

Does anybody know if i'm doing something wrong or is it a problem with the Wpf xaml parser that it cannot resolve bindings to RelativeSources during design time?

1

There are 1 best solutions below

0
On

I know this is an old question, but for the sake of posterity I have a solution that works for me.

I have never been able to get RelativeSource bindings to be Blendable. However, you can provide sign-posts to the design-time environment(s) if you are fortunate enough to have an ancestor without a binding set against it.

On the spare ancestor (in this case, the Grid) bind the DataContext to the same RelativeSource except with the Path set to just the DataContext. Then, apply a d:DataContext to the same ancestor, providing it with the type (or equivalent mock) you want to bind to on your actual, original element. Finally, bind your original element (the ComboBox) to the property or path as per normal.

<Grid 
   DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor,  
            AncestorType={x:Type Window}}, Path=DataContext, 
            Mode=OneWay}"
   d:DataContext="{Binding Source={StaticResource DesignViewModel}}" >
        <Grid.ColumnDefinitions>
           <ColumnDefinition Width="*"></ColumnDefinition>
           <ColumnDefinition Width="20"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <ComboBox Grid.Column="0" Margin="3,0,3,0" 
            ItemsSource="{Binding Path=AvailableGenres, Mode=OneWay}"
            DisplayMemberPath="Name" 
            SelectedItem="{Binding Path=Genre, Mode=TwoWay}" DataContext=" 
            {Binding}" />

</Grid>