Использование связывания Wpf RelativeSource нарушает смешиваемость
У меня есть следующий сценарий... У меня есть окно, которое содержит ItemsControl. Я указываю ViewModel для DataContext окна. Я указываю DataTemplate для ItemTontlate ItemControl. В DataTemplate я использую ComboBox, а для ItemsSource ComboBox я использую привязку RelativeSource к DataContext содержащего его окна. Во время выполнения все работает нормально, и привязка разрешается правильно, но во время разработки Cider не может подобрать ViewModel содержащего окна, к которому привязывается ItemSource.
Вот мой код (я пропустил объявления пространства имен 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 ответ
Я знаю, что это старый вопрос, но ради потомков у меня есть решение, которое работает для меня.
Мне никогда не удавалось сделать привязки RelativeSource смешиваемыми. Однако вы можете предоставлять подписывающие сообщения в среду (среды) времени разработки, если вам достаточно повезло, что у вас есть предок без привязки к нему.
На запасном предке (в данном случае Grid) свяжите DataContext с тем же RelativeSource, за исключением того, что для Path задано только DataContext. Затем примените a 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>