【Win10】開發中的新特性及原有的變動(二)

聲明:本文內容適用於 Visual Studio 2015 RC 及 Windows 10 10069 SDK 環境下,若之後有任何變動,請以新的特性爲準。html

11、x:Bind 中使用強制轉換

這點是補充上一篇文章的,當時忘了寫(-__-)bgit

場景:須要綁定顯示某個純色背景的控件的背景顏色RGB值(感受挺繞口的)。github

由於在傳統的綁定裏,因爲是動態的,並且咱們也能確保 Background 的類型爲 SolidColorBrushexpress

那麼咱們能夠這麼寫綁定:canvas

<Page
    x:Class="Build2015XamlDemo.XBindDemo2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Build2015XamlDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <Border x:Name="brd"
                    Background="Red"
                    Width="100"
                    Height="100"/>
            <Border BorderBrush="Green" BorderThickness="2">
                <StackPanel>
                    <TextBlock Text="Binding 傳統綁定" />
                    <TextBlock Text="{Binding ElementName=brd,Path=Background.Color.R}" />
                    <TextBlock Text="{Binding ElementName=brd,Path=Background.Color.G}" />
                    <TextBlock Text="{Binding ElementName=brd,Path=Background.Color.B}" />
                </StackPanel>
            </Border>
        </StackPanel>
    </Grid>
</Page>

儘管控件的 Background 屬性的類型是 Brush,但咱們已經確保爲 SolidColorBrush,所以在運行時,不會發生錯誤。app

可是,在新的綁定 x:Bind 裏這就無法編譯經過了,由於 Brush 類並不存在 Color 屬性,可是咱們已經能夠確保這裏的 Background 必定是 SolidColorBrush。在 x:Bind 裏咱們可使用強制轉換來完成這個功能。async

<Page
    x:Class="Build2015XamlDemo.XBindDemo2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Build2015XamlDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <Border x:Name="brd"
                    Background="Red"
                    Width="100"
                    Height="100"/>
            <Border BorderBrush="Green" BorderThickness="2">
                <StackPanel>
                    <TextBlock Text="Binding 傳統綁定" />
                    <TextBlock Text="{Binding ElementName=brd,Path=Background.Color.R}" />
                    <TextBlock Text="{Binding ElementName=brd,Path=Background.Color.G}" />
                    <TextBlock Text="{Binding ElementName=brd,Path=Background.Color.B}" />
                </StackPanel>
            </Border>
            <Border BorderBrush="Blue" BorderThickness="2">
                <StackPanel>
                    <TextBlock Text="x:Bind 編譯綁定" />
                    <TextBlock Text="{x:Bind Path=brd.Background.(SolidColorBrush.Color).R}" />
                    <TextBlock Text="{x:Bind Path=brd.Background.(SolidColorBrush.Color).G}" />
                    <TextBlock Text="{x:Bind Path=brd.Background.(SolidColorBrush.Color).B}" />
                </StackPanel>
            </Border>
        </StackPanel>
    </Grid>
</Page>

PS:由於 x:Bind 裏沒有 ElementName 這個舊綁定的屬性,可是 x:Bind 的上下文爲 Page 或 UserControl,而控件是 Page 或 UserControl 的成員,所以 Path 改成上面的寫法。ide

12、根據不一樣設備類型加載不一樣的 View

在上一篇裏,咱們使用了一個自定義 StateTrigger 來實如今 Desktop 和 Mobile 下顯示不一樣的文本。這對於根據設備類型適配是頗有效的。固然,園子裏的東邪獨孤(老周)給出的這篇【Win 10應用開發】如何知道UAP在哪一個平臺上運行,使用後臺代碼來判斷也是一個方法。測試

對於 View 裏僅僅須要少許區別化的話,上面兩種方法都是最理想的方案。可是,假如咱們須要 Desktop 和 Mobile 下呈現完徹底全不一樣的內容的話,上面的方法就顯得難以應付了,維護起來也麻煩。所以,須要一種方案解決這種問題。而如今微軟給出的方案就是相似於解決本地化的方法,使用特定名字的文件夾。ui

QQ截圖20150518164358

如上圖,文件夾的名字須要以"DeviceFamily-"開頭,而且以設備名稱結尾,裏面 View 的文件名必須跟文件夾外面對應的 View 的文件名一致(即這裏一樣是 MainPage)。

PS:目前已知的設備名稱有:Desktop(表明桌面系統)、Mobile(表明移動系統)、Xbox(這個你懂的)、Team(表明 Surface Hub,就是 Build 大會上那臺 72 寸你們夥)。

因爲目前官方文檔還沒出來,應該有更多的設備類型。(聽說還有個 Holographic 和 IoT,不過目前狀況沒法測試嘛~~)

細心的大家可能發現,在上面的圖片中文件夾裏的 xaml 是沒有後臺文件的。在 Visual Studio 裏建立文件選擇這個就能夠了:

QQ截圖20150518164419

那麼建立出來的文件就會像我上面圖片裏的同樣了。

十3、x:DeferLoadStrategy(延遲加載)

在 Web 開發中,比較常見的一個例子就是用戶註冊時,驗證碼只有在用戶焦點落在輸入驗證碼的文本框時纔開始正式加載,而不是頁面加載的時候就開始加載。

在 XAML 裏咱們之前可能比較常作的方案就是在頁面裏先預留一個 Image 控件,而且隱藏它,等到真正輸入驗證碼時再設置 Image 控件的 Source。

而 x:DeferLoadStrategy 則再進一步,在須要的狀況下再初始化控件。這就更加節約了內存加改善了效率了。

一、基本 Demo

XAML:

<Page x:Class="Build2015XamlDemo.XDeferLoadStrategyDemo"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:Build2015XamlDemo"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel HorizontalAlignment="Center"
                    VerticalAlignment="Center">
            <Border Width="150"
                    Height="100"
                    Background="Red"
                    x:Name="brdDeferLoad"
                    x:DeferLoadStrategy="Lazy"></Border>
            <Button Content="檢查"
                    Click="BtnCheck_Click" />
            <Button Content="加載"
                    Click="BtnLoad_Click" />
        </StackPanel>
    </Grid>
</Page>

後臺代碼:

using System;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Build2015XamlDemo
{
    public sealed partial class XDeferLoadStrategyDemo : Page
    {
        public XDeferLoadStrategyDemo()
        {
            this.InitializeComponent();
        }

        private async void BtnCheck_Click(object sender, RoutedEventArgs e)
        {
            if (brdDeferLoad == null)
            {
                await new MessageDialog("還沒加載").ShowAsync();
            }
            else
            {
                await new MessageDialog("已加載").ShowAsync();
            }
        }

        private void BtnLoad_Click(object sender, RoutedEventArgs e)
        {
            this.FindName(nameof(brdDeferLoad));
        }
    }
}

運行程序,而後點擊檢查按鈕

QQ截圖20150518180745

點擊加載按鈕

QQ截圖20150518180823

PS:執行 this.FindName 方法,XAML 樹將會檢索給定名字的控件,若是還沒初始化的話,就會初始化。

二、使用 StateTrigger 來肯定須要加載的控件

XAML:

<Page x:Class="Build2015XamlDemo.XDeferLoadStrategyDemo2"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:Build2015XamlDemo"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState x:Name="narrow">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="600" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="brdLeft.Visibility"
                                Value="Visible" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="wide">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="850" />
                    </VisualState.StateTriggers>
                    <VisualState.Storyboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="brdRight"
                                                           Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame Value="Visible"
                                                        KeyTime="0" />
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState.Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="500" />
            <ColumnDefinition Width="250" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Border Background="Red" />
        <Border Background="Green"
                x:Name="brdLeft"
                Grid.Column="1"
                x:DeferLoadStrategy="Lazy" />
        <Border Background="Blue"
                x:Name="brdRight"
                Grid.Column="2"
                x:DeferLoadStrategy="Lazy" />
    </Grid>
</Page>

效果:

jdfw

可見,在使用 Setter 或者 Storyboard 的狀況下,若是控件沒加載,那麼系統將會幫咱們加載,再也不須要在後臺代碼中調用 this.FindName 方法。

十4、InkCanvas 控件

這是一個新的控件,就像一個塗鴉畫板同樣。

測試代碼:

XAML:

<Page x:Class="Build2015XamlDemo.InkCanvasDemo"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:Build2015XamlDemo"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Column="0">
            <ComboBox x:Name="cmb"
                      SelectionChanged="ComboBox_SelectionChanged">
                <ComboBoxItem IsSelected="True">Red</ComboBoxItem>
                <ComboBoxItem>Green</ComboBoxItem>
            </ComboBox>
        </StackPanel>
        <Grid Grid.Column="1"
              Background="DarkGray">
            <Border Background="White"
                    Margin="20">
                <InkCanvas x:Name="canvas" />
            </Border>
        </Grid>
    </Grid>
</Page>

後臺代碼:

using Windows.UI;
using Windows.UI.Xaml.Controls;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace Build2015XamlDemo
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class InkCanvasDemo : Page
    {
        public InkCanvasDemo()
        {
            this.InitializeComponent();

            UpdateInkCanvas();
        }

        private void UpdateInkCanvas()
        {
            var colorStr = ((ComboBoxItem)(cmb.SelectedItem)).Content.ToString();
            Color color;
            if (colorStr == "Red")
            {
                color = Colors.Red;
            }
            if (colorStr == "Green")
            {
                color = Colors.Green;
            }

            // 必須設置,不然沒法響應設備輸入。
            canvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Pen | Windows.UI.Core.CoreInputDeviceTypes.Touch;

            var attributes = canvas.InkPresenter.CopyDefaultDrawingAttributes();
            attributes.Color = color;

            canvas.InkPresenter.UpdateDefaultDrawingAttributes(attributes);
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (canvas != null)
            {
                UpdateInkCanvas();
            }
        }
    }
}

效果:

QQ截圖20150518194130

此外,attributes 對象裏還有不少屬性能夠設置,例如筆觸大小等等,作一個「圖畫」出來可不成問題。

 

今次就講到這裏了,本來還想說一個用戶輸入數據的驗證,可是這項功能在最新的 SDK 裏已經被刪除了。並且 Windows 10 RTM 發行時也不會再有。(不排除之後更新會回來)

這是微軟官方人員在 github 上的回答(地址:https://github.com/Microsoft/Windows-universal-samples/issues/21):

QQ截圖20150520154915

 

 

轉載請保留到該頁面的連接http://www.cnblogs.com/h82258652/articles/4517357.html。謝謝!

相關文章
相關標籤/搜索