Создание адаптивного макета с помощью RelativePanel и VisualStateManager
Я пытаюсь использовать VisualStateManager внутри пользовательского элемента управления, встроенного в флипвью. но с приведенным ниже кодом не работает, несмотря на то, что он действительно похож на тот, который упоминается в Построение адаптивного макета с помощью RelativePanel
<UserControl
x:Class="JintekiArchives.Views.CardDetailsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:JintekiArchives"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AdaptiveVisualStateGroup">
<VisualState x:Name="VisualStateNarrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="descriptionPanel.(RelativePanel.Below)" Value="imageBorder" />
<Setter Target="textPanel.(RelativePanel.Below)" Value="descriptionPanel" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateNormal">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="521" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="descriptionPanel.(RelativePanel.Below)" Value="imageBorder" />
<Setter Target="textPanel.(RelativePanel.Below)" Value="descriptionPanel" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateWide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1200" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="descriptionPanel.(RelativePanel.RightOf)" Value="imageBorder" />
<Setter Target="textPanel.(RelativePanel.RightOf)" Value="descriptionPanel" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<RelativePanel Margin="20">
<RelativePanel.Background>
<ImageBrush x:Name="backgroundGrid" ImageSource="{Binding FactionImage}" Opacity="0.1" />
</RelativePanel.Background>
<StackPanel x:Name="titlePanel" Orientation="Horizontal" Margin="24"
RelativePanel.AlignTopWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True">
<TextBlock FontSize="48" FontWeight="SemiBold" Text="{Binding Title}"></TextBlock>
</StackPanel>
<StackPanel Name="imageBorder" Width="300" Height="420" Margin="24, 24"
RelativePanel.Below="titlePanel"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="false">
<Image Source="{Binding ImageSrc}" Stretch="None"/>
</StackPanel>
<StackPanel Name="descriptionPanel" Orientation="Vertical" Margin="24, 24"
RelativePanel.AlignTopWith="imageBorder"
RelativePanel.RightOf="imageBorder">
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock>
<Run FontWeight="Bold" Text="Faction : "></Run>
<Run Text="{Binding Faction}"></Run>
</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock>
<Run FontWeight="Bold" Text="Set : "></Run>
<Run Text="{Binding Set}"></Run>
</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock>
<Run FontWeight="Bold" Text="Type : "></Run>
<Run Text="{Binding Type}"></Run>
</TextBlock>
</StackPanel>
</StackPanel>
<StackPanel Name="textPanel" Orientation="Vertical" Margin="24,24"
RelativePanel.AlignTopWith="imageBorder"
RelativePanel.RightOf="descriptionPanel">
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Width="600" TextWrapping="Wrap" TextTrimming="WordEllipsis" Text="{Binding Text}"></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Width="600" TextWrapping="Wrap" TextTrimming="WordEllipsis" FontStyle="Italic" Text="{Binding Flavor}">
</TextBlock>
</StackPanel>
<StackPanel Padding="5" Orientation="Horizontal" Margin="5">
<TextBlock>
<Run Text="Illustrated by "></Run>
<Run Text="{Binding Illustrator}"></Run>
</TextBlock>
</StackPanel>
</StackPanel>
</RelativePanel>
</Grid>
</UserControl>
1 ответ
Проблема здесь связана с конфликтующими отношениями с RelativePanel
в вашем макете.
Если вы установите несколько отношений, которые нацелены на один и тот же край элемента, в результате вы можете иметь конфликтующие отношения в макете. Когда это происходит, отношения применяются в следующем порядке приоритета:
- Отношения выравнивания панели ( AlignTopWithPanel, AlignLeftWithPanel,…) применяются первыми.
- Отношения выравнивания родственного брата ( AlignTopWith, AlignLeftWith,…) применяются вторыми.
- Позиционные отношения родственного брата ( Above, Below, RightOf, LeftOf) применяются последними.
Свойства выравнивания по центру панели ( AlignVerticalCenterWith, AlignHor HorizontalCenterWithPanel,...) обычно используются независимо от других ограничений и применяются, если нет конфликта.
Свойства HorizontalAlignment и VerticalAlignment в элементах пользовательского интерфейса применяются после оценки и применения свойств отношений. Эти свойства управляют размещением элемента в пределах доступного размера для элемента, если требуемый размер меньше доступного размера.
Так что приоритет AlignTopWith
выше чем Below
, И в своем коде вы установили RelativePanel.AlignTopWith
в imageBorder
в descriptionPanel
а также textPanel
, Поэтому настройки как descriptionPanel.(RelativePanel.Below)
в VisualState
не сработает
Чтобы решить эту проблему, я предлагаю вам удалить вложенные свойства RelativePanel
в вашем descriptionPanel
а также textPanel
и просто установите эти прикрепленные свойства в VisualState
без использования AlignTopWith
,
Поскольку я не уверен, какой у вас требуемый макет, здесь я просто использую два визуальных состояния, например:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AdaptiveVisualStateGroup">
<VisualState x:Name="VisualStateNarrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="descriptionPanel.(RelativePanel.Below)" Value="imageBorder" />
<Setter Target="textPanel.(RelativePanel.Below)" Value="descriptionPanel" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateWide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1200" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="descriptionPanel.(RelativePanel.Below)" Value="titlePanel" />
<Setter Target="descriptionPanel.(RelativePanel.RightOf)" Value="imageBorder" />
<Setter Target="textPanel.(RelativePanel.Below)" Value="titlePanel" />
<Setter Target="textPanel.(RelativePanel.RightOf)" Value="descriptionPanel" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>