使用Wpf RelativeSource绑定会破坏Blendability

时间:2012-01-09 14:06:22

标签: wpf binding relativesource blendability

我有以下场景......我有一个包含ItemsControl的窗口。我为Window的DataContext指定了一个ViewModel。我为ItemControl的ItemTemplate指定了一个DataTemplate。在DataTemplate中我使用ComboBox,对于ComboBox的ItemsSource,我使用RelativeSource Binding来包含Window的DataContext。在运行时期间一切正常并且Binding正确解析,但在Design-Time Cider期间无法获取ItemSource绑定到的包含Window的ViewModel。

这是我的代码(我在顶部省略了xml名称空间声明,但在我的代码中包含了它们):

<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>

因此,基本上从上面的代码片段中,Path = DataContext.AvailableGenres在设计时无法解析,但在运行时它正确解析。

有人知道我是做错了还是Wpf xaml解析器在设计时无法解析与RelativeSources的绑定问题?

1 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,但为了后人,我有一个适合我的解决方案。

我从来没有能够将RelativeSource绑定变为Blendable。但是,如果您有幸拥有一个没有绑定设置的祖先,您可以为设计时环境提供签名。

在备用祖先(在本例中为Grid)将DataContext绑定到相同的RelativeSource 除外),并将Path设置为DataContext。然后,将d:DataContext应用于同一祖先,为其提供要在实际原始元素上绑定的类型(或等效模拟)。最后,按照正常情况将原始元素(ComboBox)绑定到属性或路径。

<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>