Demo下載:http://yunpan.cn/cFjgPtWRHKH9H  访问密码 c4b7

顧名思義,視圖狀態管理器。

在WPF中,它的功能似乎更強大。在UWP中,閹割了GotElementState方法,導致它只能在控件內部使用。

這個東東一般用來突出某些操作,以提醒用戶。它原來是狀態A,後來用戶進行了某些操作,我們就會根據用戶的操作,判斷他想要做什麼,然後根據他的目的,顯示狀態B。最容易理解的例子就是按鈕,它普通狀態,鼠標放上去以後,變成了另一種狀態,點擊又是另一種狀態。

1.按鈕狀態

我們先來看看,按鈕有哪些狀態。首先我們來編輯一個按鈕模板:XAML面板中,添加一個按鈕,並在它上面右鍵->編輯模板->編輯副本,截圖如下:

然後,我們就可以得到一個按鈕的副本:

<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}"/>
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
<Setter Property="Padding" Value="8,4,8,4"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid">
<Grid.Background>
<SolidColorBrush x:Name="bkBrush" Color="LightGray" />
</Grid.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>                     <!------------- 我加的狀態 --------------->
<VisualState x:Name="testState">
<Storyboard>
<ColorAnimation To="Red" Storyboard.TargetName="bkBrush" Storyboard.TargetProperty="Color" Duration="0:0:2" EnableDependentAnimation="True" />
</Storyboard>
</VisualState> </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

在上面的代碼中,可以看到鼠標有 "Normal" "PointerOver" "Pressed" "Disabled" 四種狀態。意思一看就知道。

那麼這些狀態是怎麼執行的呢?由誰來執行呢?

為了解答這個問題,我添加了一個狀態 "testState"。我添加了一個按鈕,單擊來調用它。

private void button1_Click(object sender, RoutedEventArgs e)
{
Windows.UI.Xaml.VisualStateManager.GoToState(button, "testState", true);
}

一點擊button1,就使用 GoToState 調用另一個按鈕的狀態。具體效果看我Demo.

那麼我們能調用 PointerOver之類的狀態嗎?答案是肯定的。它由誰來調用,答案也呼之欲出,Button來調用。Button是一個控件,我們只要捕獲鼠標消息,然後在消息處理函數那裡調用 GoToState, 那這一切不就順理成章了嗎?

2.UserControl

所以我又寫了一個UserControl,當鼠標放上去時,改變它的背景顏色。

<UserControl
x:Class="VisualStateManager.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:VisualStateManager"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<SolidColorBrush x:Name="RedBrush" Color="Red" />
</UserControl.Resources> <Grid x:Name="rootGrid" PointerEntered="rootGrid_PointerEntered" Background="Gray" PointerExited="rootGrid_PointerExited">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualStateGroup.States>
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="rootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource RedBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup.States>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>

看Grid的消息響應:

PointerEntered="rootGrid_PointerEntered" Background="Gray" PointerExited="rootGrid_PointerExited"
        private void rootGrid_PointerEntered(object sender, PointerRoutedEventArgs e)
{
Windows.UI.Xaml.VisualStateManager.GoToState(this, "PointerOver", true);
} private void rootGrid_PointerExited(object sender, PointerRoutedEventArgs e)
{
Windows.UI.Xaml.VisualStateManager.GoToState(this, "Normal", true);
}

然後效果就出來了,鼠標一放上去,背景顏色變紅。SO EASY。

但是,如果你仔細看,Normal 狀態,發現它什麼也不做,那為什麼它什麼也不做會還原為原來的灰色背景呢?

3.狀態執行的細節

我們就必須要了解這個細節了:

1. 如果控件要转换到的新State有Storyboard,运行该Storyboard。如果控件的旧State有Storyboard,结束其运行。 
2. 如果控件已处于新state状态(即新旧State相同),则GoToState不执行任何操作并返回true。 
3. 如果新State在控件的ControlTemplate中不存在,则GoToState不执行任何操作并返回 false。

以上細節摘自:http://www.cnblogs.com/KeithWang/archive/2012/03/30/2425588.html

4.觸發器自動跳轉狀態

據我研究,微軟只提供了窗口大小改變,然後觸發狀態。。感覺功能很局限啊。不知道有沒有大神知道更多的,然後偷偷地告訴我。

這個東東,最常用的就是當窗口大小改變時,改變程式的界面佈局。假設有一個圖片瀏覽工具,當窗口寬度為100的時候,你只顯示一列。當窗口寬度為200的時候,你就顯示兩列。

又如微軟的視頻顯示中的那樣,在手機中,操作按鈕放在程式最下方,在PC上,操作按鈕放在最右邊。。這個時候可以使用這個東東。。我寫了一個當窗口寬度大於600時,自動拉伸按鈕長度的狀態:

        <VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="600" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="button1.Width" Value="500" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

如果是改變按鈕的位置,如顯示在下方,改變到顯示到右方,可以看我的這篇博客:WIN10-UWP開發之控件。或許看微軟的示例。

好了,就寫到這裡了。

【WIN10】VisualStateManager使用說明的更多相关文章

  1. JavaFX結合 JDBC, Servlet, Swing, Google Map及動態產生比例圖 (2):JavaFX建立及程式碼說明 (转帖)

    說明:就如同標題一樣,前端會用到JavaFX.Swing.Java Web Start.Google Map 的技術, 後端就是JDBC.Servlet的技術,以及我們會簽署認證jar檔案,這樣才可存 ...

  2. man page分類與說明

    轉載自http://itzone.hk/article/article.php?aid=200407152225014657 (如有侵權,請留言或來信告知) 前言 Man page是每位程式設計員及U ...

  3. [DE2i-150] 重建PCIe_Fundmental範例說明

    以下資料的整理主要是做備忘錄,避免以後忘了,順便留給需要的人. ========================================== 本文主要是參考友晶科技的DE2i-150光碟裡面的 ...

  4. open和opener使用說明

    父網頁:window.open("article.html")子網頁:var dialoginfo=$('#dialogdata',window.opener.document); ...

  5. vi 常用命令使用說明

    vi是一種文字模式全螢幕文字編輯軟體(Text Editor).對初學者來說,vi是個很難用的工具,一般需要2個星期的時間才能得心應手.之所以介紹vi,其理由如下: vi是Unix上的標準文字編輯軟體 ...

  6. 【转】UniGUI Session管理說明

    [转]UniGUI Session管理說明 (2015-12-29 15:41:15) 转载▼   分类: uniGUI 台中cmj朋友在uniGUI中文社区QQ群里发布的,转贴至此. UniGUI ...

  7. GlusterFS六大卷模式說明

    GlusterFS六大卷說明   第一,分佈卷 在分布式卷文件被随机地分布在整个砖的体积.使用分布式卷,你需要扩展存储,冗余是重要或提供其他硬件/软件层.(簡介:分布式卷,文件通过hash算法随机的分 ...

  8. NUC970 U-Boot 使用說明

    U-Boot 使用說明U-Boot 是一個主要用於嵌入式系統的開機載入程式, 可以支援多種不同的計算機系統結構, 包括ARM.MIPS.x86與 68K. 這也是一套在GNU通用公共許可證之下發布的自 ...

  9. 【转载】GlusterFS六大卷模式說明

    本文转载自翱翔的水滴<GlusterFS六大卷模式說明> GlusterFS六大卷說明 第一,分佈卷 在分布式卷文件被随机地分布在整个砖的体积.使用分布式卷,你需要扩展存储,冗余是重要或提 ...

随机推荐

  1. JavaScript的基本介绍

    JavaScript入门介绍 输出语句:document.write()   1.执行顺序:从上到下,每一天语句是要加分号的,如果不加的话,浏览器会默认帮你自动添加,分号.   2.注释:一行注释就是 ...

  2. 灰色预测 GM11模型

    灰色预测实现见:https://www.jianshu.com/p/a35ba96d852b from pandas import Series from pandas import DataFram ...

  3. ubuntu 14.04安装JDK

    As a workaround, you can install OpenJDK 8 from a PPA repository: 1. Open terminal from the Dash or ...

  4. jQuery选择器——(三)

    1.基本元素选择器 id选择器:$(“#id名称”); 元素选择器:$(“元素名称”); 类选择器:$(“.类名”); 通配符:* 多个选择器共用(并集) 2.层级选择器 ancestor desce ...

  5. python3之pymysql模块

    1.python3 MySQL数据库链接模块 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb. PyMySQL 遵循 Pyt ...

  6. HaoZipC不是内部或外部命令

    Win7专业版,32位,HaoZip V3.2 将安装命令下HaoZipC.exe,HaoZip.dll,lang\HaoZipLang_chs.dll三个文件拷贝到C:\Windows\System ...

  7. shell系统检测->

    系统状态检测脚本练习 1-> 查看磁盘状态 思路:查看磁盘/当前使用状态,如果使用率超过80%则报警发邮件 1.获取磁盘当前使用的值 df -h|grep /$ 2.从获取到的值中提取出,对应的 ...

  8. 记录一下mariadb设置主从同步的过程[虚拟机测试]

    背景:因为工作的关系,需要找寻实时同步数据到另外系统的服务器的数据库上,查询下来,用mariadb进行跨服务器的同步数据动作,用主从同步比较多,也比较保险 也有使用shell脚本的,定时定候的执行my ...

  9. JAVA随笔(三)

    私有是针对类的,而不是对象. static 函数,其实是类函数.之前一直不太理解每个类中的static main是什么意思,为什么main中不能直接调用非静态的变量:因为main是 类函数,不是属于某 ...

  10. github后端开发面试题大集合(一)

    作者:小海胆链接:https://www.nowcoder.com/discuss/3614?type=0&order=0&pos=5&page=0?from=wb来源:牛客网 ...