使用 VisualStateManager 在 Windows 10 应用程序中移动 MainPage.xaml 中的 UserControl
Move a UserControl in MainPage.xaml in Windows 10 application using VisualStateManager
我的页面 (XAML) 中有一个 UserControl,它代表一个工具栏,位于页面顶部,具有三个按钮。由于这是一个 Windows 10 应用程序,我希望当屏幕宽度较宽时,这个顶部工具栏会沿着屏幕的左边缘移动,以便垂直显示工具栏。我尝试使用 VisualStateManager VisualStates,但这只会帮助更改属性而不是元素。我需要将 ColumnDefinitions 更改为 RowDefinitions 以便垂直显示按钮。
我现在唯一的解决方案是创建第二个 UserControl (VerticalToolBar.xaml) 并使用 VSM 隐藏和取消隐藏两者。但我确信对于可能很常见的事情有更简单的解决方案。我想使用一个 UserControl,因为现在我正在复制他们的代码。它们的行为相同。
这是 TopHorizontalToolBar.xaml 的 XAML:
<UserControl
x:Class="Innobec.Mobile.Apps.CityScope.UserControls.TopHorizontalToolBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Innobec.Mobile.Apps.CityScope.UserControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="80"
d:DesignWidth="400">
<Grid x:Name="MainToolbar">
<Grid Grid.Row="0" Background="Red">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button x:Name="pinButton" HorizontalAlignment="Center" Grid.Column="0" Background="Red" Click="pinButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-Pin-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="newsButton" HorizontalAlignment="Center" Grid.Column="1" Background="Red" Click="newsButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-News-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="weatherButton" HorizontalAlignment="Center" Grid.Column="2" Background="Red" Click="weatherButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-Weather-Icon-60px.png" Stretch="None"/>
</Button>
</Grid>
</Grid>
我的 VerticalToolBar 除了使用 .在我的 MainPage.xaml 上,我有以下显示我放置这些用户控件的位置:
<Page
x:Class="Innobec.Mobile.Apps.CityScope.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Innobec.Mobile.Apps.CityScope"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:maps="using:Windows.UI.Xaml.Controls.Maps"
xmlns:toolbars="using:Innobec.Mobile.Apps.CityScope.UserControls"
mc:Ignorable="d">
<Grid x:Name="MainGrid">
<Grid.Resources>
<Storyboard x:Name="SlideInfoUp">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LocationDetails" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
<SplineDoubleKeyFrame KeyTime="0:0:0.25" Value="130"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="SlideInfoDown">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LocationDetails" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
<SplineDoubleKeyFrame KeyTime="0:0:0.25" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WindowStates">
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="660"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TopBarGrid.Visibility" Value="Collapsed"/>
<Setter Target="LeftBarGrid.(Grid.Column)" Value="0"/>
<Setter Target="LeftBarGrid.(Grid.RowSpan)" Value="3"/>
<Setter Target="LeftBarGrid.Visibility" Value="Visible"/>
<Setter Target="LeftBarGrid.Width" Value="Auto"/>
<Setter Target="ContentGrid.(Grid.Row)" Value="1"/>
<Setter Target="ContentGrid.(Grid.Column)" Value="1"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TopBarGrid.(Grid.Row)" Value="0"/>
<Setter Target="TopBarGrid.(Grid.ColumnSpan)" Value="2"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftColumn" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid x:Name="TopBarGrid">
<toolbars:TopHorizontalToolBar/>
</Grid>
<Grid x:Name="LeftBarGrid" Grid.Column="0" Grid.RowSpan="2" Visibility="Collapsed" Width="60">
<toolbars:VerticalToolBar />
</Grid>
<Grid x:Name="ContentGrid" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView x:Name="itineraryListView"
Grid.Row="1"
Margin="24,24,0,0"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<RelativePanel Margin="0,24,0,0">
<TextBlock x:Name="address"
Width="100"
TextWrapping="Wrap"
Text="{Binding FormattedAddress}"/>
<ListView
ItemsSource="{Binding ItineraryInfosAtPoint}"
RelativePanel.RightOf="address"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativePanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid>
<maps:MapControl x:Name="InfoMap"
Loaded="InfoMap_Loaded"
MapElementClick="InfoMap_MapElementClick"
TransitFeaturesVisible="False"
BusinessLandmarksVisible="False"
LandmarksVisible="True"
ZoomLevelChanged="InfoMap_ZoomLevelChanged"
MapServiceToken="qB0QfPpDYI6Qh8SWJvS5~x5_U5L-2_-eVF0AE_2qg2w~AuuXeJ_QLZ_6APb7Y3vr3x_opC-CkytS298EJUAjPpPo6pSj1hzYpCIdCTUkH1pf"/>
</Grid>
</Grid>
<Grid Grid.Row="2" Grid.Column="1"><!--Grid.ColumnSpan="2"-->
<Viewbox MaxWidth="500" HorizontalAlignment="Left" VerticalAlignment="Center">
<toolbars:LocationDetails x:Name="LocationDetails" Height="0"/>
</Viewbox>
</Grid>
<Grid Grid.Row="3" Grid.ColumnSpan="2">
<toolbars:BottomToolBar x:Name="BottomToolBar"/>
</Grid>
</Grid>
一种选择是使用 StackPanel 代替 Grid 来放置按钮。然后,您可以通过视觉状态改变水平和垂直方向,快速切换面板布局。
还有一个 Windows10 选项是使用全新的 RelativePanel 来固定按钮。此控件允许您定义其中的子项相对于彼此的位置。对于水平布局,每个按钮都可以设置在前一个按钮的右侧,对于垂直布局,每个按钮都可以设置在下方。这些相关属性也可以通过视觉状态进行更改。对于水平视图,上面的控件看起来像这样。
<RelativePanel >
<Button x:Name="pinButton" Background="Red" Click="pinButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-Pin-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="newsButton" Background="Red" Click="newsButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}"
RelativePanel.RightOf="pinButton">
<Image Source="/Assets/Top-News-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="weatherButton" Background="Red" Click="weatherButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}"
RelativePanel.RightOf="newsButton">
<Image Source="/Assets/Top-Weather-Icon-60px.png" Stretch="None"/>
</Button>
</RelativePanel>
这是一篇很好的博客 post,更深入地介绍了 RelativePanel 并为其设置视觉状态:
http://blog.galasoft.ch/posts/2015/04/building-adaptive-layout-in-windows-10-with-relativepanel-and-adaptivetrigger/
我的页面 (XAML) 中有一个 UserControl,它代表一个工具栏,位于页面顶部,具有三个按钮。由于这是一个 Windows 10 应用程序,我希望当屏幕宽度较宽时,这个顶部工具栏会沿着屏幕的左边缘移动,以便垂直显示工具栏。我尝试使用 VisualStateManager VisualStates,但这只会帮助更改属性而不是元素。我需要将 ColumnDefinitions 更改为 RowDefinitions 以便垂直显示按钮。
我现在唯一的解决方案是创建第二个 UserControl (VerticalToolBar.xaml) 并使用 VSM 隐藏和取消隐藏两者。但我确信对于可能很常见的事情有更简单的解决方案。我想使用一个 UserControl,因为现在我正在复制他们的代码。它们的行为相同。
这是 TopHorizontalToolBar.xaml 的 XAML:
<UserControl
x:Class="Innobec.Mobile.Apps.CityScope.UserControls.TopHorizontalToolBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Innobec.Mobile.Apps.CityScope.UserControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="80"
d:DesignWidth="400">
<Grid x:Name="MainToolbar">
<Grid Grid.Row="0" Background="Red">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button x:Name="pinButton" HorizontalAlignment="Center" Grid.Column="0" Background="Red" Click="pinButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-Pin-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="newsButton" HorizontalAlignment="Center" Grid.Column="1" Background="Red" Click="newsButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-News-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="weatherButton" HorizontalAlignment="Center" Grid.Column="2" Background="Red" Click="weatherButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-Weather-Icon-60px.png" Stretch="None"/>
</Button>
</Grid>
</Grid>
我的 VerticalToolBar 除了使用 .在我的 MainPage.xaml 上,我有以下显示我放置这些用户控件的位置:
<Page
x:Class="Innobec.Mobile.Apps.CityScope.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Innobec.Mobile.Apps.CityScope"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:maps="using:Windows.UI.Xaml.Controls.Maps"
xmlns:toolbars="using:Innobec.Mobile.Apps.CityScope.UserControls"
mc:Ignorable="d">
<Grid x:Name="MainGrid">
<Grid.Resources>
<Storyboard x:Name="SlideInfoUp">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LocationDetails" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
<SplineDoubleKeyFrame KeyTime="0:0:0.25" Value="130"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="SlideInfoDown">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LocationDetails" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
<SplineDoubleKeyFrame KeyTime="0:0:0.25" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WindowStates">
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="660"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TopBarGrid.Visibility" Value="Collapsed"/>
<Setter Target="LeftBarGrid.(Grid.Column)" Value="0"/>
<Setter Target="LeftBarGrid.(Grid.RowSpan)" Value="3"/>
<Setter Target="LeftBarGrid.Visibility" Value="Visible"/>
<Setter Target="LeftBarGrid.Width" Value="Auto"/>
<Setter Target="ContentGrid.(Grid.Row)" Value="1"/>
<Setter Target="ContentGrid.(Grid.Column)" Value="1"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TopBarGrid.(Grid.Row)" Value="0"/>
<Setter Target="TopBarGrid.(Grid.ColumnSpan)" Value="2"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftColumn" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid x:Name="TopBarGrid">
<toolbars:TopHorizontalToolBar/>
</Grid>
<Grid x:Name="LeftBarGrid" Grid.Column="0" Grid.RowSpan="2" Visibility="Collapsed" Width="60">
<toolbars:VerticalToolBar />
</Grid>
<Grid x:Name="ContentGrid" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView x:Name="itineraryListView"
Grid.Row="1"
Margin="24,24,0,0"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<RelativePanel Margin="0,24,0,0">
<TextBlock x:Name="address"
Width="100"
TextWrapping="Wrap"
Text="{Binding FormattedAddress}"/>
<ListView
ItemsSource="{Binding ItineraryInfosAtPoint}"
RelativePanel.RightOf="address"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativePanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid>
<maps:MapControl x:Name="InfoMap"
Loaded="InfoMap_Loaded"
MapElementClick="InfoMap_MapElementClick"
TransitFeaturesVisible="False"
BusinessLandmarksVisible="False"
LandmarksVisible="True"
ZoomLevelChanged="InfoMap_ZoomLevelChanged"
MapServiceToken="qB0QfPpDYI6Qh8SWJvS5~x5_U5L-2_-eVF0AE_2qg2w~AuuXeJ_QLZ_6APb7Y3vr3x_opC-CkytS298EJUAjPpPo6pSj1hzYpCIdCTUkH1pf"/>
</Grid>
</Grid>
<Grid Grid.Row="2" Grid.Column="1"><!--Grid.ColumnSpan="2"-->
<Viewbox MaxWidth="500" HorizontalAlignment="Left" VerticalAlignment="Center">
<toolbars:LocationDetails x:Name="LocationDetails" Height="0"/>
</Viewbox>
</Grid>
<Grid Grid.Row="3" Grid.ColumnSpan="2">
<toolbars:BottomToolBar x:Name="BottomToolBar"/>
</Grid>
</Grid>
一种选择是使用 StackPanel 代替 Grid 来放置按钮。然后,您可以通过视觉状态改变水平和垂直方向,快速切换面板布局。
还有一个 Windows10 选项是使用全新的 RelativePanel 来固定按钮。此控件允许您定义其中的子项相对于彼此的位置。对于水平布局,每个按钮都可以设置在前一个按钮的右侧,对于垂直布局,每个按钮都可以设置在下方。这些相关属性也可以通过视觉状态进行更改。对于水平视图,上面的控件看起来像这样。
<RelativePanel >
<Button x:Name="pinButton" Background="Red" Click="pinButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}">
<Image Source="/Assets/Top-Pin-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="newsButton" Background="Red" Click="newsButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}"
RelativePanel.RightOf="pinButton">
<Image Source="/Assets/Top-News-Icon-60px.png" Stretch="None"/>
</Button>
<Button x:Name="weatherButton" Background="Red" Click="weatherButton_Click" Style="{StaticResource TopHorizontalToolBarButtonStyle}"
RelativePanel.RightOf="newsButton">
<Image Source="/Assets/Top-Weather-Icon-60px.png" Stretch="None"/>
</Button>
</RelativePanel>
这是一篇很好的博客 post,更深入地介绍了 RelativePanel 并为其设置视觉状态: http://blog.galasoft.ch/posts/2015/04/building-adaptive-layout-in-windows-10-with-relativepanel-and-adaptivetrigger/