Use UWP to implement a layout similar to win10 settings page, uwpwin10
I wonder if someone has noticed how to set the page layout in Win10? The page will adjust the display content based on different window widths, and even the operation of the back button is different in different widths, as shown in the figure:
Is it cool? In this article, we will make a similar layout.
First, add all the items to be displayed to the page. The page is as follows:
1 <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> 2 <Grid. rowDefinitions> 3 <RowDefinition Height = "30"> </RowDefinition> 4 <RowDefinition Height = "*"> </RowDefinition> 5 </Grid. rowDefinitions> 6 7 <! -- Big title, back button --> 8 <StackPanel Grid. row = "0" Orientation = "Horizontal" x: Name = "fullPanel"> 9 <Button Content = "Back" x: name = "full_back" Click = "full_back_Click"> </Button> 10 <TextBlock Margin = "10, 0, 0, 0 "> This is a big title </TextBlock> 11 </StackPanel> 12 13 14 <! -- Subtitle, the back button, only displayed when the width of the desktop is less than 500 --> 15 <StackPanel Grid. row = "0" Orientation = "Horizontal" x: Name = "detailPanel"> 16 <Button x: name = "detail_back" Content = "Back" Click = "detail_back_Click"> </Button> 17 <TextBlock Margin = "10, 0, 0, 0 "> This is a subtitle </TextBlock> 18 </StackPanel> 19 20 <! -- Content --> 21 <RelativePanel Grid. Row = "1"> 22 <! -- List --> 23 <ListView x: Name = "left" IsItemClickEnabled = "True" ItemClick = "left_ItemClick" SelectedIndex = "-1"> 24 <ListView. itemTemplate> 25 <DataTemplate> 26 <StackPanel Margin = "10"> 27 <TextBlock> 28 <Run Text = "Item: "> </Run> 29 <Run Text =" {Binding} "> </Run> 30 </TextBlock> 31 </StackPanel> 32 </DataTemplate> 33 </ListView. itemTemplate> 34 </ListView> 35 36 <! -- For more information about the right half of the video, see <Grid x: Name = "right"> 38 <StackPanel> 39 <TextBlock> .. </TextBlock> 40 <TextBlock> 41 <Run Text = "Item:"> </Run> 42 <Run Text = "{Binding SelectedItem, elementName = left} "Foreground =" Red "> </Run> 43 </TextBlock> 44 </StackPanel> 45 </Grid> 46 </RelativePanel> 47 </Grid>
Bind test data to the backend:
1 private void MainPage_Loaded(object sender, RoutedEventArgs e)2 {3 this.left.ItemsSource = Enumerable.Range(1, 10).ToList();4 }
Run it to see the effect. It's a bit messy. Don't worry, Let's adjust it slowly.
1 <VisualStateManager. VisualStateGroups> 2 <! -- The VisualState in this group only adjusts the layout for the window width and does not involve devices --> 3 <VisualStateGroup x: Name = "windowSize"> 4 <! -- Wide screen settings --> 5 <VisualState x: Name = "wide"> 6 <VisualState. StateTriggers> 7 <! -- If the value is greater than or equal to 501, the screen is even larger .. --> 8 <AdaptiveTrigger min1_wwidth = "501"> </AdaptiveTrigger> 9 </VisualState. StateTriggers> 10 <VisualState. Setters> 11 <! -- Set --> 12 <! -- Hide Subtitle --> 13 <Setter Target = "detailPanel. Visibility" Value = "Collapsed"> </Setter> 14 15 <! -- Display the title. Although the title is displayed by default, You need to reset the display attribute because we will modify the display attribute through code in the future --> 16 <Setter Target = "fullPanel. visibility "Value =" Visible "> </Setter> 17 18 <! -- Display content on the right --> 19 <Setter Target = "right. Visibility" Value = "Visible"> </Setter> 20 21 <! -- For a wide screen, the content on the right should be at the right of the list --> 22 <Setter Target = "right. (RelativePanel. rightOf) "Value =" left "> </Setter> 23 24 <! -- Display content on the left --> 25 <Setter Target = "left. visibility "Value =" Visible "> </Setter> 26 </VisualState. setters> 27 </VisualState> 28 29 <! -- Narrow screen settings --> 30 <VisualState x: Name = "narrow"> 31 <VisualState. StateTriggers> 32 <! -- 0-500 is a small window --> 33 <AdaptiveTrigger min1_wwidth = "0"> </AdaptiveTrigger> 34 35 </VisualState. StateTriggers> 36 <VisualState. Setters> 37 <! -- The subtitle is displayed by default --> 38 <Setter Target = "detailPanel. Visibility" Value = "Visible"> </Setter> 39 40 <! -- Hide the title and click back to display the title. --> 41 <Setter Target = "fullPanel. Visibility" Value = "Collapsed"> </Setter> 42 43 <! -- Display the content on the right and hide it after clicking the subtitle. --> 44 <Setter Target = "right. Visibility" Value = "Visible"> </Setter> 45 46 <! -- Hide content on the left --> 47 <Setter Target = "left. visibility "Value =" Collapsed "> </Setter> 48 </VisualState. setters> 49 </VisualState> 50 </VisualStateGroup> 51 </VisualStateManager. visualStateGroups>
Running it to see if the effect is much better. Is it a bit interesting to adjust the window width now?
But the back button still has no effect. here we need to use code to control it, but this is very simple, because we use different buttons in different la S, the advantage is that you do not need to use code to determine the window status. Here we only paste the background code, which is also very simple.
1 private void full_back_Click (object sender, RoutedEventArgs e) 2 {3 // For our page, the full_back button should be hidden, because there is no previous page 4 //, we ignore it here, but the buttons are still available. You can make a hidden logic by yourself. 5} 6 7 private void detail_back_Click (object sender, routedEventArgs e) 8 {9 // here is why we reset the attribute in VisualState 10 11 // display the list12 on the left // hide the right content 13 this. left. visibility = Visibility. visible; 14 this. right. visibility = Visibility. collapsed; 15 16 // hide subtitle 17 // Display primary Title 18 this. fullPanel. visibility = Visibility. visible; 19 this. detailPanel. visibility = Visibility. collapsed; 20} 21 22 private void left_ItemClick (object sender, ItemClickEventArgs e) 23 {24 // here we need to determine whether to switch to hide 25 if (this. actualWidth <= 500) 26 {27 // display the left-side list28 // hide the right-side content 29 this. left. visibility = Visibility. collapsed; 30 this. right. visibility = Visibility. visible; 31 32 // hide subtitle 33 // Display primary title 34 this. fullPanel. visibility = Visibility. collapsed; 35 this. detailPanel. visibility = Visibility. visible; 36} 37}
At this point, our page's behavior and settings are a bit like!
Here, the basic functions of this page are almost the same, and then the details are improved (in fact, there is still a small problem, And the status switching is somewhat different from the setting ).
1. When the window width is greater than 500, a fixed width is directly provided for the list to be wider.
2. When the window width is less than 500, fill the list with the entire page. Here we need to talk about a feature of RelativePanel (it should be a feature ..), Its internal controls do not automatically stretch to fill the internal space. Even if you use HorizontalAlignment/verticalignment, the Grid won't work !! We need to use the RelativePanel. AlignXXXX series of attributes to stretch as needed.
In our page, we need to align the top, bottom, and bottom of the narrow screen to fill the page.
1 <! -- Stretch the list on the left to fill the page --> 2 <Setter Target = "left. (RelativePanel. alignRightWithPanel) "Value =" True "> </Setter> 3 <Setter Target =" left. (RelativePanel. alignBottomWithPanel) "Value =" True "> </Setter> 4 <Setter Target =" left. (RelativePanel. alignLeftWithPanel) "Value =" True "> </Setter> 5 <Setter Target =" left. (RelativePanel. alignTopWithPanel) "Value =" True "> </Setter>
Final effect!
The example in this article is just a simple layout. If you want to implement complicated functions, you can consider changing the Grid on the right to a Frame and then navigate to different pages through the ListItem on the left, to display different contents.