注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

分享,态度 ·~~

—— 十年太长,五年;如果可以回到五年前,你最想对那时候的自己说什么?

 
 
 

日志

 
 

WinRT自定义Button的另一个例子  

2012-05-31 09:34:38|  分类: Windows 8 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
接前一篇自定义控件的内容(在这里),现介绍另一个例子。因为最近在做Windows8的Metro app,Contract和Async之类的点很久以前就提过了,这两篇主要介绍控件的使用,大家可以举一反三。
今天要介绍的是四个状态的按钮(FourStateButton):“鼠标悬浮”、“按下(有记忆)”、“正常”、“无效” 四种状态。所谓 “有记忆的按下”状态,即需要再一次触按才能把已“按下“的Button状态还原。这样的Button在工程里非常常用。这里提供两种方式实现这样的按钮:一种是重写ToggleButton;另一种则是控件模拟。

1、重写ToggleButton。其实ToggleButton就是有四种状态的按钮,但是默认的表现力差,重写Style可以满足大部分需求:

<Style x:Key="DropDownToggleStyle" TargetType="ToggleButton">
<Setter Property="MinWidth" Value="236"/>
<Setter Property="MinHeight" Value="38"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Rectangle x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle.Fill>
<ImageBrush ImageSource="../Assets/asus_win8_dropdown_n.png"/>
</Rectangle.Fill>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<ImageBrush ImageSource="../Assets/asus_win8_dropdown_n.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<ImageBrush ImageSource="../Assets/asus_win8_dropdown_o.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<ImageBrush ImageSource="../Assets/asus_win8_dropdown_p.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<ImageBrush ImageSource="../Assets/asus_win8_dropdown_d.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Rectangle>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WinRT自定义Button的另一个例子 - 乂乂 - 一个人,一支烟  ·~~
 
2、写自定义控件模拟。
XAML文件:

<Grid PointerPressed="Grid_PointerPressed" PointerReleased="Grid_PointerReleased"
PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited">
<Grid.Background>
<ImageBrush ImageSource="../Assets/asus_win8_redbtn_n.png"/>
</Grid.Background>
<Grid x:Name="gridVirtualBG" IsHitTestVisible="True" Visibility="Collapsed"/>
... ...
</Grid>

CS文件:

private bool isDetailOpen = false;

private void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)
{
ImageBrush imgBrush = new ImageBrush();
imgBrush.ImageSource = new BitmapImage(new Uri("ms-appx:/Assets/asus_win8_redbtn_p.png"));
gridVirtualBG.Background = imgBrush;
gridVirtualBG.Visibility = Visibility.Visible;

DetailView detailView = DetailView.GetView();
if (!detailView.IsOpen)
{
isDetailOpen = false;
// Do something.
}
else
{
isDetailOpen = true;
}
}

private void Grid_PointerReleased(object sender, PointerRoutedEventArgs e)
{
DetailView detailView = DetailView.GetView();
if (isDetailOpen)
{
// Do something.
gridVirtualBG.Visibility = Visibility.Collapsed;
}

}

private void Grid_PointerEntered(object sender, PointerRoutedEventArgs e)
{
ImageBrush imgBrush = new ImageBrush();
imgBrush.ImageSource = new BitmapImage(new Uri("ms-appx:/Assets/asus_win8_redbtn_o.png"));
gridVirtualBG.Background = imgBrush;
gridVirtualBG.Visibility = Visibility.Visible;
}

private void Grid_PointerExited(object sender, PointerRoutedEventArgs e)
{
DetailView detailView = DetailView.GetView();
if (detailView.IsOpen)
{
ImageBrush imgBrush = new ImageBrush();
imgBrush.ImageSource = new BitmapImage(new Uri("ms-appx:/Assets/asus_win8_redbtn_p.png"));
gridVirtualBG.Background = imgBrush;
gridVirtualBG.Visibility = Visibility.Visible;
}
else
{
gridVirtualBG.Visibility = Visibility.Collapsed;
}
}

WinRT自定义Button的另一个例子 - 乂乂 - 一个人,一支烟  ·~~
 
当然上面两种方式中重写ToggleButton是最简单的,看起来UI和逻辑也拆分得很清楚。但是也有很多时候我们的Button需要更多花样,这也是我在第二个方案里放”Grid“模拟而不是一般的”Rectangle“的原因,在里面可以放任意我想放的东西,并且通过代码来控制行为,这比Template+Binding的方式要灵活太多。并且封装在UserControl的逻辑代码也让整个控件很清晰。用第二种方案的另一个优势是,状态转换非常平滑,我在这里写了两个Grid来交替显示,状态的转换非常柔和;而Temple则在图片替换时会有闪烁的情况,即前一个状态的图片消失,后一状态的图片尚未加载,这个显现在图片像素较大时非常明显。
  评论这张
 
阅读(1674)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017