我有以下场景......我有一个包含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的绑定问题?
答案 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>