以下是我个人的学习笔记,欢迎大家提出疑问,我们一起探讨。
github
XAML -XML Syntax, create instances of Classes that define the UI
Type Converters - Convert literal strings in XAML into enumerations, instances of classes, etc
Default Prpperty … Ex. sets Content property
<Button>click MeButton>
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
...
...
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
<StackPanel>
<TextBlock>TopTextBlock>
<TextBlock>BottomTextBlock>
StackPanel>
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
属性
It basically defines an area within which you can position and align child objects
or in relation to the parent panel
用于在Relative Panel内定位的附加属性(Attach Property)有三大类:
以上优先级从高到低
APP > Window > Frame > MainPage
You can load pages into a child frame or into the root frame.
rootFrame.Navigate(typeof(MainPage),e.Argument)
MyFrame.Navigate(typeof(Page1))
,同时能使得MainPage中定义的导航栏能存在多个页面中MyFrame.Navigate(typeof(Page1));
-定义后退按钮
if (MyFrame.CanGoBack) {
MyFrame.GoBack();
}
if (MyFrame.CanGoForward()) {
MyFrame.GoForward();
}
<HyperlinkButton Content="Go to Page 2" Click="HyperlinkButton_Click">
<HyperlinkButton Content="Go to Microsoft.com" NavigateUri="http://www.microsoft.com">
Frame.Navigate(typeof(Page1), TextBox.text);
同时,要在下一个页面中设置接受这个参数的方法。在对应Page的xaml.cs中的页面构造函数的下面加上OnNavigatedTo函数:
protected override void OnNavigatedTo(NavigationEventArgs e) {
var value = (string)e.Parameter;
TextBox.Text = Value;
}
internal static string SomeImportant Value;
然后在每个页面的OnNavigateTo函数中替换为:
if (!String.IsNullOrEmpty(App.SomeImportantvalue)) {
ValueTextBox.Text = App.SomeImportantValue;
}
注意:IsChecked是可空布尔类型(nullable bool),所以若想得到true or false那么需要将其强制性转换为bool
控件
CheckBoxResultTextBlock.Text = MyCheckBox.IsChecked.ToString()
;RadioButtonTextBlock.Text=(bool)YesRadioButton.IsChecked ? Yes : No;
if (ComboBoxResultTextBlock == null) return;
var combo = (ComboBox)sender;
var item = (ComboBoxItem)combo.SelectedItem;
ComboBoxResultTextBlock.Text = item.Content.ToString();
var selectedItems = MyListBox.Items.Cast()
.Where(p => p.IsSelected)
.Select(t => t.Content.ToString())
.ToArray();
ListBoxResultTextBlock.Text = string.Join(",", selectedItems);
Image
ToggleButton(切换按钮)
ToggleButtonResultTextBlock.Text=MyToggleButton.Ischeckes.ToString();
ToggleSwitch (拨动开关)
TimePicker(时间选择器)
CalendarDatePicker(日历选择器)
CalendarView(日期查看)
var selectedDates = sender.SelectedDates.Select(p => p.Date.Month.ToString() + "/" + p.Date.day.ToString()).ToArray();
var values = string.Join(", ", selectedDates);
CanlendarViewResultTextBlock.Text = values;
Flyout
<Button>
<Button.Flyout>
<Flyout x:Name="MyFlyout">
....
Flyout>
Button.Flyout>
Button>
MenuFlyout
AutoSuggestBox(建议列表)
var autoSuggestBox = (AutoSuggestBox)sender;
var filtered = selectionItems.Where(p => p.StartsWith(autoSuggestBox.Text)).ToArray();
autoSuggestBox.ItemsSource = filtered;
其中,selectionItems是我们预先设置的一个字符数组。
Slider(滑块控件)
ProgressBar (进度条)
Value="{x:Bind MySlider.Value, Mode=OneWay}"
ProgressRing (进度圈)
IsActive (True/False)
软件推荐
<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"; }
}
可以用于输入框提示语,一旦鼠标焦点在文本框中时,自动清除该提示语,否则就会显示该提示语(在没有任何输入的情况下)
属性:
将ScrollViewer放在StackPanel中会导致滚动条不显示的情况,但是,如果把StackPanel作为ScrollViewer的子类就不会出现这种情况
<Style TargetType="Button" x:Key="MyButtonStyle">
<Setter Property="Background" Value="Blue" />
<Setter Property="FontFamily" Value="Arial Black" />
<Setter Property="FontSize" Value="36" />
Style>
<Button Style="{StaticResource MyButtonStyle}" />
<Page.Resources>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml">
ResourceDictionary.MergedDictionaries>
Page.Resources>
以上的资源绑定是静态的,它只在APP首次运行时进行一次。所以在APP的生命周期中它不会再发生改变。
- StateTriggers 状态触发器
- Setters 属性设置器
<Grid Name="ColorGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="VisualStatePhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ColorGrid.Background" Value="Red" />
<Setter Target="MessageTextBlock.FontSize" Value="18" />
VisualState.Setters>
VisualState>
<VisualState x:Name="VisualStateTablet">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="600" />
VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ColorGrid.Background" Value="Yellow" />
<Setter Target="MessageTextBlock.FontSize" Value="36" />
VisualState.Setters>
VisualState>
<VisualState x:Name="VisualStateDesktop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="800" />
VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ColorGrid.Background" Value="Blue" />
<Setter Target="MessageTextBlock.FontSize" Value="54" />
VisualState.Setters>
VisualState>
VisualStateGroup>
VisualStateManager.VisualStateGroups>
源代码
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="Wide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="800" />
VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="First.(Grid.Row)" Value="0" />
<Setter Target="First.(Grid.Column)" Value="0" />
<Setter Target="Second.(Grid.Row)" Value="0" />
<Setter Target="Second.(Grid.Column)" Value="1" />
<Setter Target="Third.(Grid.Row)" Value="0" />
<Setter Target="Third.(Grid.Column)" Value="2" />
<Setter Target="First.(Grid.ColumnSpan)" Value="1" />
<Setter Target="Second.(Grid.ColumnSpan)" Value="1" />
<Setter Target="Third.(Grid.ColumnSpan)" Value="1" />
VisualState.Setters>
VisualState>
<VisualState x:Name="Narrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="First.(Grid.Row)" Value="0" />
<Setter Target="First.(Grid.Column)" Value="0" />
<Setter Target="Second.(Grid.Row)" Value="1" />
<Setter Target="Second.(Grid.Column)" Value="0" />
<Setter Target="Third.(Grid.Row)" Value="2" />
<Setter Target="Third.(Grid.Column)" Value="0" />
<Setter Target="First.(Grid.ColumnSpan)" Value="3" />
<Setter Target="Second.(Grid.ColumnSpan)" Value="3" />
<Setter Target="Third.(Grid.ColumnSpan)" Value="3" />
VisualState.Setters>
VisualState>
VisualStateGroup>
VisualStateManager.VisualStateGroups>
Visual Blend的使用
Three ways to set specific DeviceFamily XAML Views in UWP
实现不同设备有不同的XAML Views。
...
xmlns:data="using:xBindDataExample.Models">
"data:Book" x:Key="BookDataTemplate">
"Center">
"{x:Bind CoverImage}" />
"{x:Bind Title}" />
"{x:Bind Author}" />
...
"{x:Bind Books}"
IsItemClickEnabled="True"
ItemClick="GridView_ItemClick"
ItemTemplate="{StaticResource BookDataTemplate}">
...
Code Behind
------------
public sealed partial class MainPage : Page
{
private List Books;
public MainPage()
{
this.InitializeComponent();
Books = BookManager.GetBooks();
}
private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
var book = (Book)e.ClickedItem;
ResultTextBlock.Text = "You selected " + book.Title;
}
}
If the contents of List
will change, make sure you use ObservableCollection
instead!
ObservableCollection<> 保持监视和监听
当集合的内容改变时,它会提醒GridView更新从而达到实时更新的效果。
Binding是动态绑定,Bind是静态绑定。使用Bind的时候,如果修改了绑定的对象,即将原来的替换成新的,那有可能在编译的时候出现错误。原因是Bind采用的是预编译,仍使用的是旧的代码。此时我们可以剪切data tempalate,然后等待一会再粘贴回去。
MVVM means Model View View Model
如果你想使用VisualStateManager以及AdaptiveTriggers来调整你的数据模板中的控件,则需要User Control。
If you intend to combine the VisualStateManager with data bound controls, you will need to put your Data Template code inside of a User Control, then create the VisualStateManager code inside of the User Control.
1) Create a User Control.
2) Cut the Data Template out of the MainPage.xaml
and copy it into the User Control.
3) Reference the User Control from inside the Data Template:
<local:ContactTemplate HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
4) Modify the contents of the User Control changing x:Bind statements to utilize object.property notation:
<UserControl>
<StackPanel>
<Image Source="{x:Bind Contact.AvatarPath}" />
<TextBlock Text="{x:Bind Contact.FirstName}" />
<TextBlock Text="{x:Bind Contact.LastName}" />
StackPanel>
UserControl>
5) Add this in the User Control’s Code Behind:
public Models.Contact Contact { get { return this.DataContext as Models.Contact; } }
public ContactTemplate()
{
this.InitializeComponent();
this.DataContextChanged += (s, e) => Bindings.Update();
}
(1) 创建Converter文件夹,在其中加入一个类文件:BooleanToVisibilityConverter,代码如下:
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
namespace Todos.Converters
{
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language) {
bool visibility = (bool)value;
return visibility ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, string language) {
throw new NotImplementedException();
}
}
}
(2)在需要使用的页面定义命名空间:
xmlns:c="using:Todos.Converters"
(3)调用转换器
<Line Grid.Column="2" Stretch="Fill" Stroke="Black" StrokeThickness="2" X1="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Visibility= "{Binding IsChecked, ElementName=MyCheckBox, Converter={StaticResource booleanToVisibilityConverter}}" />
详见我个人博文:UWP:Live Tile && Adaptive Tile && Updating
详见我个人博文:App to App communication
UWP:使用MediaPlayerElement实现媒体播放器