現代作業系統應用開發
以下是我個人的學習筆記,歡迎大家提出疑問,我們一起探討。
github 1.XAML XAML只是特定格式的XML,它遵循所有XML的規則。XML的使用者就是將我們的代碼變成windows10可執行檔的編譯器; XAML是一種簡單的建立類的執行個體並設定屬性的方法,代碼量比C#節省了很多。 XAML中的類型轉換器使得使用者在設定屬性時能用一些非常簡潔的字元來代替冗長的類型名和枚舉值
XAML -XML Syntax, create instances of Classes that define the UI
Type Converters - Convert literal strings in XAML into enumerations, instances of classes, etc 2.Grid && Stackpanel Grid 與 Stackpanel 都會將某些特定的控制項如image、retangular自動擴充至100%,但Grid會將其儲存格內的元素自動置中,且Grid內元素可以重疊,而Stackpanel就不行了。 所以大部分布局可以用StackPanel進行,但是並不是說Grid一無是處,它在適應性變化中還是能起到很好的作用的,而這是StackPanel無法做到的。 3.Understanding Default Properties, Complex Properties and the property Element Syntax
Default Prpperty … Ex. sets Content property
<Button>click Me</Button>
Complex Properties - Break out a property into its own element syntax:
<Button Name="ClickMeButton" HorizonalAlignment="Left" Content="Click Me" Margin="20,20,0,0" VerticalAlignment="Top" Click="ClickMeButton_Click" Width="200" Heigh="100" > <Button.Background> <LinearGradientBrush Endpoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="Red" Offset="1"/> </LinearGradientBrush> </Button.Background></Button>
Elements put themselves into rows and columns using attached property syntax
... ... <Button Grid.Row="0" /></Grid>
When referencing Rows and Columns … 0-based. There’s always one default implicit cell: Row 0, Column 0 If not specified, element will be in the default cell
4.Understanding XAML Schemas and Namesoace Declarations Don’t touch the schema stuff - It’s necessary! Schemas define rules for XAML, for UWP, for designer support, etc. Namesoaces tell XAML parser where to find the definition rules for a given element in the XAML.
5.XAML layout with Grids
Layout controls don’t have a content properety …
they have a Children property of type UIElementCollection.
By embedding any control inside of a layout control, you are implicitly calling the Add method of the Children collection Property.
<Grid Background="Black"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinition> <Grid.ColumnDefinitions></Grid.ColumnDefinition></Grid>
Sizes expressed in terms of :
- Auto -Use the largest value of elements it contains to define the width / height
- *(star sizing) -Utilize all the available space
- 1* -of all available space, give me 1 “share”
- 2* -of all available space, give me 2 “shares”
- 3* -of all available space, give me 3 “shares”
6 total shares … 3* would be 50% of the available width / height 6.XAML layout with Stackpanel
<StackPanel> <TextBlock>Top</TextBlock> <TextBlock>Bottom</TextBlock></StackPanel>
Vertical Orientation by default. Left-to-right flow by default when Horizontal aligment Most layouts will combine multiple layout controls. Grid will overlap controls. StackPanel will stack them.
7.SplitView
The split view allows us to create a panel that can be displayed or hidden.
We would use the SplitView to implement hamburger navogation.
There are two parts to a SplitView:
(1) The part that is hidden by default(Pane)
(2) The part that is shown by default(Content)
SplitView可用於實現菜單。
隱藏在展示部分旁邊的部分,我們稱之為Pane
很容易背覆蓋或者被推開的用於展示的部分,我們稱之為Content
屬性 IsPaneOpen DisplayMode Inline 把Content推開來讓Pane表示,但Pane關閉時不顯示 Overlap 把Content完全遮擋住,但Pane關閉時不顯示 CompactOverlay 把Content完全遮擋住,但Pane關閉時有顯示
需要設定CompactPaneLength CompactInline 把Content推開讓Pane表示,但Pane關閉時顯示 CompactPaneLength 用於設定Pane關閉時的寬度 OpenPaneLength 用於設定Pane開啟時的寬度 - 8.Relative Panel
It basically defines an area within which you can position and align child objects in relation to each other
or in relation to the parent panel
用於在Relative Panel內定位的附加屬性(Attach Property)有三大類: 面板對齊關係(Panel Alignment Relationship):如將控制項與面板頂端對其,靠左對齊等 同級對齊關係(Sibling Alignment Relationship):用於同級元素的對齊,如控制項間的頂端對齊,靠左對齊等。 同級位置關係(Sibling Position Relationship):用於放置同級元素,如控制項的上、下、左、右等。
以上優先順序從高到低 附加屬性:
AlignRightWithPanel (True/False) AlignLeftWith (the name of controls) LeftOf (the name of controls) AlignVerticalCenterWith (the name of controls) AlignHorizontalCenterWithPanel (True/False) AlignBottomWithPanel (True/False) AlignTopWith (the name of controls) 9.Navigation
APP > Window > Frame > MainPage
You can load pages into a child frame or into the root frame. 在UWP裡,頁面時存在於Frame Object裡。 當APP啟動的時候,會有一個最進階的Application Object,在裡面會有一個視窗,在案頭版本的UWP裡,它會顯示頂部的一欄,就是有“最小化”、“最大化”、“關閉”按鈕,以及應用程式名稱的那一欄。在裡面,是Frame,用於存放頁面(Pages)。 在APP.xaml.cs中會有向MainPage跳轉的代碼rootFrame.Navigate(typeof(MainPage),e.Argument) 為了在Mainpage中像APP一樣匯入匯出頁面,我們可以在MainPage中定義一個Frame,然後在MainPage()函數中加入MyFrame.Navigate(typeof(Page1)),同時能使得MainPage中定義的導覽列能存在多個頁面中 定義跳轉按鈕
MyFrame.Navigate(typeof(Page1));
-定義後退按鈕
if (MyFrame.CanGoBack) { MyFrame.GoBack();} 定義前進按鈕
if (MyFrame.CanGoForward()) { MyFrame.GoForward();} HyperlinkButton按鈕
<HyperlinkButton Content="Go to Page 2" Click="HyperlinkButton_Click"><HyperlinkButton Content="Go to Microsoft.com" NavigateUri="http://www.microsoft.com">
在定義MainPage外的頁面時,使用Frame.Navigate而不是MyFrame。因為MyFrame是處於MainPage中,不在其它頁面中。 為了實現前進保留之前頁面資訊,我們可以在Frame.Navigate中引入第二個參數,實現資料的傳遞,如:
Frame.Navigate(typeof(Page1), TextBox.text);
同時,要在下一個頁面中設定接受這個參數的方法。在對應Page的xaml.cs中的頁面建構函式的下面加上OnNavigatedTo函數:
protected override void OnNavigatedTo(NavigationEventArgs e) { var value = (string)e.Parameter; TextBox.Text = Value;} 為了實現後退資訊的儲存,其實我們可以將我們所要儲存的資訊放在一個靜態變數中(範圍在本app內,加在App類中): Create a global variable by declaring a static internal field in the App class definition.
internal static string SomeImportant Value;
然後在每個頁面的OnNavigateTo函數中替換為:
if (!String.IsNullOrEmpty(App.SomeImportantvalue)) { ValueTextBox.Text = App.SomeImportantValue;}
10.基本XAML控制項
注意:IsChecked是可空布爾類型(nullable bool),所以若想得到true or false那麼需要將其強制性轉換為bool 怎麼使用。 如何將控制項顯示在螢幕上 如何處理主要事件,例如選擇或點擊 如何檢索所控制的值,無論何種類型、性質
控制項 CheckBox(複選框)
Name Content Tapped
CheckBoxResultTextBlock.Text = MyCheckBox.IsChecked.ToString(); RadioButton
Name Content GroupName Checked
RadioButtonTextBlock.Text=(bool)YesRadioButton.IsChecked 。 Yes : No; CombBox
SelectionChanged 子標籤: CombBoxItem
Content IsSelected
if (ComboBoxResultTextBlock == null) return;var combo = (ComboBox)sender;var item = (ComboBoxItem)combo.SelectedItem;ComboBoxResultTextBlock.Text = item.Content.ToString();
ListBox ListBox 將是學習漢堡菜單(Hambuger navigation)製作中重要的控制項 Name SelectionMode (Multiple/Single) SelectionChanged 子標籤: ListBoxItem
var selectedItems = MyListBox.Items.Cast<ListBoxItem>() .Where(p => p.IsSelected) .Select(t => t.Content.ToString()) .ToArray();ListBoxResultTextBlock.Text = string.Join(",", selectedItems);
Image Source HorizontalAlignment Width Height Grid.Row Grid.Column Stretch
None Fill,將圖片展開以填滿空間 Uniform,將圖片按原比例縮放到一個正好的大小 UniformToFill Margin
ToggleButton(切換按鈕) Name Content IsThreeState Click ToggleButtonResultTextBlock.Text=MyToggleButton.Ischeckes.ToString();
ToggleSwitch (撥動開關) 複雜屬性
OffContent OnContent
TimePicker(時間選取器) ClockIdentifier(12HourClock/24HourClock)
CalendarDatePicker(日曆選取器) PlaceholderText
CalendarView(日期查看) SelectionMode(Multiple、None、Single) SelectedDatesChanged 將選擇的日期呈現出來
var selectedDates = sender.SelectedDates.Select(p => p.Date.Month.ToString() + "/" + p.Date.day.ToString()).ToArray();var values = string.Join(", ", selectedDates);CanlendarViewResultTextBlock.Text = values;
Flyout MyFlyout.Hide();
<Button> <Button.Flyout> <Flyout x:Name="MyFlyout"> .... </Flyout> </Button.Flyout></Button>
MenuFlyout Placement
Bottom Full Left Right Top MenuFlyoutItem MenuFlyoutSubItem
建議使用MenuFlyoutSubItem的Items屬性,把下一級的菜單元素寫到這個屬性裡 MenuFlyoutSeparator (劃線分隔) ToggleMenuFlyoutItem (被選中左側有打勾)
AutoSuggestBox(建議列表) 如果在含有搜尋特性的應用中,這個控制項將非常有用 它的樣式與我們用TextBox定義的搜尋方塊差不多 它能隨著我們輸入的文本變化而縮小選擇的範圍
var autoSuggestBox = (AutoSuggestBox)sender;var filtered = selectionItems.Where(p => p.StartsWith(autoSuggestBox.Text)).ToArray();autoSuggestBox.ItemsSource = filtered;
其中,selectionItems是我們預先設定的一個字元數組。 QueryIcon PlaceholderText TextChanged
Slider(滑塊控制項) Maximum Mininum
ProgressBar (進度條) Maxinum Value
Value="{x:Bind MySlider.Value, Mode=OneWay}"
ProgressRing (進度圈)
IsActive (True/False)
軟體推薦 XAML UI Control 11. Hamburger Navigation Character Map 的Segoe MDL2 Assets中找表徵圖 整體MainPage
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <RelativePanel> <Button Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="" FontSize="36" Click="HamburgerButton_Click" /> </RelativePanel> <SplitView Name="MySplitView" Grid.Row="1" DisplayMode="CompactOverlay" OpenPaneLength="200" CompactPaneLength="56" HorizontalAlignment="Left"> <SplitView.Pane> <ListBox SelectionMode="Single" Name="IconsListBox" SelectionChanged="IconsListBox_SelectionChanged"> <ListBoxItem Name="ShareListBoxItem"> <StackPanel Orientation="Horizontal"> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="36" Text="" /> <TextBlock Text="Share" FontSize="24" Margin="20,0,0,0" /> </StackPanel> </ListBoxItem> <ListBoxItem Name="FavoritesListBoxItem"> <StackPanel Orientation="Horizontal"> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="36" Text="" /> <TextBlock Text="Favorites" FontSize="24" Margin="20,0,0,0" /> </StackPanel> </ListBoxItem> </ListBox> </SplitView.Pane> <SplitView.Content> <TextBlock Name="ResultTextBlock" /> </SplitView.Content> </SplitView> </Grid> 後台
private void HamburgerButton_Click(object sender, RoutedEventArgs e) { MySplitView.IsPaneOpen = !MySplitView.IsPaneOpen; } private void IconsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ShareListBoxItem.IsSelected) { ResultTextBlock.Text = "Share"; } else if (FavoritesListBoxItem.IsSelected) { ResultTextBlock.Text = "Favorites"; } }
12.TextBox 的 PlaceholderText=”“
可以用於輸入框提示,一旦滑鼠焦點在文字框中時,自動清除該提示,否則就會顯示該提示(在沒有任何輸入的情況下) 13.ScrollViewer
屬性: HorizontalScrollBarVisibility VertiacalScrollBarVisibility
設定為auto表明捲軸只在需要的時候顯示,不需要的時候隱藏
將ScrollViewer放在StackPanel中會導致捲軸不顯示的情況,但是,如果把StackPanel作為ScrollViewer的子類就不會出現這種情況 通常,我們會把ScrollViewer放在應用的整個可見地區中 14.畫布與圖形 都有Tapped屬性設定事件 放在畫布中可以利用畫布的附加屬性管理這些圖形控制項 Canvas allows you to do absolute positioning via attached properties. Line
x1 x2 Y1 Y2 Stroke(外圍顏色) Fill(內部顏色) StrokeThickness StrokeEndLineCap (尾部的形狀) StrokeStartLineCap Polyline
Stroke StrokeThickness Fill Points StrokeLineJoin StrokeStartLineCap Rectangle Ellipse (橢圓) Canvas.ZIndex 相當於三維中的Z軸,可以用來定義控制項重疊的方式,即可以定義頂層為指定控制項,ZIndex的值越大,那它所在的層次也就越高,最大值也就代表最高層次的控制項。 15.Page.Resources 當我們要綁定一個resource的時候,需要的表達格式就是大括弧裡面有”StaticResource”,在加上resource的名字(key)。 大括弧時綁定的意思,而”StaticResource”這個詞表明了我們所綁定資源的類型 如果一個個設定就太複雜了,是否有類似於css中style那樣作用於同一類的設定,那便是將style標籤加入Resources中
<Style TargetType="Button" x:Key="MyButtonStyle"> <Setter Property="Background" Value="Blue" /> <Setter Property="FontFamily" Value="Arial Black" /> <Setter Property="FontSize" Value="36" /></Style>
在控制項中設定其Style屬性
<Button Style="{StaticResource MyButtonStyle}" /> 如果我想將Resource應用在APP中的各個頁面以及控制項中,需要在APP.XAML中的Application.Resources元素上建立該Resources 我們也可以將這些設定寫入檔案中,就像web一樣將css寫入檔案中。 建立Resource Dictionary,然後在我們想要使用的頁面中調用它
<Page.Resources> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Dictionary1.xaml"> </ResourceDictionary.MergedDictionaries></Page.Resources>
以上的資源綁定是靜態,它只在APP首次運行時進行一次。所以在APP的生命週期中它不會再發生改變。 佈景主題資源的設定使得我們開發的應用能夠根據使用者裝置的主題設定來設定我們應用的樣式。 我們可以從不同的主題設定中選擇,來實現使用者選擇的顏色和主題色,無論是案頭端、手機端還是XBox 可以請求佈景主題色彩變化
<App RequestTheme="Light">
高對比的主題會強行覆蓋你的所有主題和風格 16.VisualStateGroup
- StateTriggers 狀態觸發器- Setters 屬性設定器
<