Windows App开发之常用控件与应用栏
2015-09-08 00:00
666 查看
控件的属性、事件与样式资源
如何添加控件
添加控件的方式有多种,大家更喜欢下面哪一种呢?1)使用诸如Blend for Visual Studio或Microsoft Visual Studio XAML设计器的设计工具。
2)在Visual Studio XAML编辑器中将控件添加到XAML代码中。
3)在代码中添加控件。 注意:当应用运行时会看到你在代码中添加的控件,但在 Visual Studio XAML 设计器中看不到。
前面我们通过在工具箱拖住控件以及直接在写XAML代码来设置控件,在教程的后面,我们会看到在C#后台代码中添加控件。Blend我们暂时还没有用到,不过其在绘制图形和动画上可谓非常强大和优秀。
设置控件的属性
控件的属性相比大家都已经会用了,一来可以直接在XAML中添加属性,二来可以在属性视图中添加和修改属性。![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/4e8a9019d8e9341ffce62a51b064fd96.jpg)
为控件添加事件
如果要添加和修改事件呢,同样在属性视图中,点击右上角的闪电图标即可。如果要添加Click事件,那么在Click的输入框中输入好事件名称后直接按Enter即可。此时VS就会自动跳转到C#后台代码中,第一个参数sender是对处理程序所附加的对象的应用,第二参数是事件数据,它通常在签名中显示为e参数。private void btnSetStyle_Click(object sender, RoutedEventArgs e) { Button b = (Button)sender; b.Height = 400; b.Width = 320; }
上面的这段代码这会将所点击的Button的高设置为400,宽设置为320;除了这种方式外,也可以按如下操作,其中btnSetStyle是当前Button的名字:
private void btnSetStyle_Click(object sender, RoutedEventArgs e) { btnSetStyle.Height = 400; btnSetStyle.Width = 320; }
除此之外,我们也可以不在XAML中定义Click事件,按照如下操作也可以达到相同的效果,它会将两个事件相互关联。
public MainPage()
{
this.InitializeComponent();
btnSetStyle.Click += new RoutedEventHandler(btnSetStyle_Click);
}
private void btnSetStyle_Click(object sender, RoutedEventArgs e) { btnSetStyle.Height = 400; btnSetStyle.Width = 320; }
为控件设置样式资源
即便没有添加过资源,也不清楚什么是样式,没关系,想必大家都玩过2048吧。游戏中有许多方格,那这些方格的样式会不会一个个去定义呢,当然不是,可以直接用样式资源来定位到所有的Button。以下是一个基本样式,
<Page.Resources> <Style TargetType="Button"> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="FontSize" Value="40"/> <Setter Property="HorizontalAlignment" Value="Center"></Setter> <Setter Property="VerticalAlignment" Value="Center"></Setter> <Setter Property="Background" Value="Gray"></Setter> <Setter Property="Width" Value="100"></Setter> <Setter Property="Height" Value="100"></Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid x:Name="Grid" Background="Transparent"> <Border x:Name="Border" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Background="{TemplateBinding Background}" > <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Page.Resources>
但是这里也有一个问题,如果我们有10个Button控件,却只想其中8个用到这些定义,另外2个想用另一种控件,那该怎么办呢?
将样式定义为资源,其实是有2中方式的。
一种就是直接用Style的TargetType属性来定义到所有的目标控件。
另一种则除了用TargetType属性外,还可以用x:key属性,然后再具体的控件中庸显式的关键字StaticResource来设置具体的Style属性。
<Page.Resources> <Style TargetType="Button"> <Setter Property="FontStyle" Value="Oblique" /> <Setter Property="FontSize" Value="20" /> <Setter Property="BorderBrush" Value="Green" /> <Setter Property="BorderThickness" Value="5" /> <Setter Property="Foreground" Value="Orange" /> <Setter Property="Height" Value="80"/> <Setter Property="Width" Value="160"/> </Style> <Style x:Key="OtherStyle" TargetType="Button"> <Setter Property="FontStyle" Value="Italic" /> <Setter Property="FontSize" Value="16" /> <Setter Property="Foreground" Value="Lavender" /> <Setter Property="Height" Value="160"/> <Setter Property="Width" Value="320"/> <Setter Property="Opacity" Value="0.2"/> </Style> </Page.Resources>
具体效果见下图,其中Opacity属性为透明度。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/68ac985ad1bbb6ae5b92c069b79ce10c.jpg)
大家都知道类可以继承,样式也是可以继承的。
部分控件介绍
通过前面的学习,已经见过一些控件了,现在起将逐步见到更多控件。但由于控件太多,教程中无法一一介绍,请自行举一反三。教程内容也将不断更新。Button
前面最常用的控件就是Button了,Button还有一个有意思的属性,当把鼠标指针放在Button上时,就会在Button的头顶冒出一串文本。<Button ToolTipService.ToolTip="Go to www.blog.csdn.net/nomasp" Margin="692,458,0,230"/>
Button有一个很有意思的属性。
<Button Content="摩天轮" Margin="134,363,0,367"> <ToolTipService.ToolTip> <Image MaxHeight="80" MaxWidth="100" Source="Assets/343219.jpg"/> </ToolTipService.ToolTip> </Button>
只要把鼠标放到Button上面就会显示出这张图片了,也叫做帮助提示吧。其实更简单的方法是下面这种。它显示的是一个后退的样式,而且鼠标放上去会有文字Back提示。
<Button Content="摩天轮" ToolTipService.ToolTip="Back" Style="{StaticResource NavigationBackButtonNormalStyle}" />
ToggleSwitch
这个控件和Button很像,它像开关一样。<ToggleSwitch x:Name="toggleSwitch1" Header="NoMasp Toggle" OnContent="On" OffContent="Off" Toggled="ToggleSwitch_Toggled" Margin="409,468,0,227"/> <ToggleSwitch x:Name="toggleSwitch2" Header="NoMasp Toggle" OnContent="On" OffContent="Off" IsOn="True" Toggled="ToggleSwitch_Toggled" Margin="409,565,0,130"/>
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/63a2d64e44bf71b9a62dd5006eb79079.jpg)
MessageDialog
这控件和Button一起讲还蛮合适的,我们随意添加一个Button,然后写好Click事件如下。private async void Button_Click(object sender, RoutedEventArgs e) { Windows.UI.Popups.MessageDialog messageDialog = new Windows.UI.Popups.MessageDialog("噢,你刚刚踩到了地雷!"); await messageDialog.ShowAsync(); }
注意要在函数上加上async表示异步。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/12a8d928985217d1c62d106cf14b6aef.jpg)
如果需要预览效果,可以参见教程随后的“用浮出控件做预览效果”。
ComboBox
ComboBox提供了下拉列表,自然也是一个很常用的控件。<ComboBox Height="50" Width="200" Name="cbox1" SelectionChanged="cbox1_SelectionChanged" Margin="17,47,1049,671"> <x:String>Select 1</x:String> <x:String>Select 2</x:String> <x:String>Select 3</x:String> <x:String>Select 4</x:String> </ComboBox>
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/5d1e2aacc0cc0aaea3cd36f974eed7a5.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/b0ccdce01524f5c954680cac722f8436.jpg)
ListBox
ListBox控件和ComboBox很相似,都可以让用户选择已经嵌入在列表中的选项。用法如下:<ListBox x:Name="listBox1" SelectionChanged="listBox1_SelectionChanged" Width="100"> <x:String>Item 1</x:String> <x:String>Item 2</x:String> <x:String>Item 3</x:String> </ListBox>
DatePicker、TimePicker
Winows平台设置时间的控件倒是很有特色,就是DatePicker和TimePicker。<DatePicker Foreground="Red" Header="NoMasp Date" Margin="3,177,0,533"/> <TimePicker Foreground="Green" Header="NoMasp Time" Margin="3,246,0,464" Width="289"/>
以下既是截图,也是写这篇教程的时间。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/e186779ed3509aeb7043cadb5efbd28d.jpg)
这个控件的更多介绍也在教程随后的“时间控件的更多介绍”中。
FlipView
FlipView是一个可以让用户逐个浏览的项目集合的控件,下面是相关的示例代码。CommonAssets文件夹完全可以定义在Shared目录下,这样WP也可以拿来用了。<FlipView> <Image Source="CommonAssets/5083.jpg"/> <Image Source="CommonAssets/5503.jpg"/> <Image Source="CommonAssets/6121.jpg"/> </FlipView>
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/43fd27c6a43d9b5df513ce5b4fa95572.jpg)
除此之外呢,我们还可以在后台代码中添加,下面的第二段代码和第一段类似,不过是用的List。
FlipView flipView = new FlipView(); flipView.Items.Add("Item 1"); flipView.Items.Add("Item 2"); flipView.SelectionChanged += filpView_SelectionChanged; grid1.Children.Add(flipView);
List<String> listItems = new List<string>(); listItems.Add("Item 1"); listItems.Add("Item 2"); FlipView flipView = new FlipView(); flipView.ItemsSource = listItems; flipView.SelectionChanged += filpView_SelectionChanged; grid1.Children.Add(flipView);
除了这2种方式之外呢,用CollectionViewSource来绑定数据也是完全没问题的。
<Page.Resources> <CollectionViewSource x:Name="collectionVSFlipView" Source="{Binding Items}"/> </Page.Resources>
上面是一段资源文件,然后FlipView ListView的ItemsSource添加静态资源绑定就OK了。
<FlipView x:Name="flipView" ItemsSource="{Binding Source={StaticResource collectionVSFlipView}}"/>
如果大家自己试过FlipView就会发现它的图片资源等都是左右滚动的,如果要用上下滚动呢?那就用下面这个ItemsPanelTemplate模板就好了。
<FlipView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Vertical"/> </ItemsPanelTemplate> </FlipView.ItemsPanel>
ScrollBar
如果有缩放图片,并且可以滚动以查看图片的需要,那么就可以用ScrollBar啦。这主要是能留给图片的位置太小以至于图片无法全部显示出来。<ScrollViewer ZoomMode="Enabled" MaxZoomFactor="12" HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" VerticalScrollMode="Enabled" Height="200" Width="200" Margin="363,35,803,533"> <Image Source="CommonAssets/6121.jpg" Height="400" Width="400"/> </ScrollViewer>
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/1f210d25290380ec062618f84fd67736.jpg)
Viewbox
还有一个控件则可以将图片等缩放到指定的大小的,那就是Viewbox。大家看看下面这个图,是不是很炫酷呢。<Viewbox MaxHeight="33" MaxWidth="33" Margin="23.5,35,-26,-35"> <Image Source="CommonAssets/5503.jpg" Opacity="0.9 "/> </Viewbox> <Viewbox MaxHeight="66" MaxWidth="66" Margin="26,35,-26,-35"> <Image Source="CommonAssets/5503.jpg" Opacity="0.6"/> </Viewbox> <Viewbox MaxHeight="99" MaxWidth="99" Margin="26,35,-26,-35"> <Image Source="CommonAssets/5503.jpg" Opacity="0.3"/> </Viewbox>
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/0ffe42d60252dec60ad4364846372dda.jpg)
GridView
相信大家都已经看过了GridView控件,很多Modern应用都会采用的。其和ComboBox挺类似的。<GridView x:Name="gView1" SelectionChanged="gView1_SelectionChanged"> <x:String>Item 1</x:String> <x:String>Item 2</x:String> <x:String>Item 3</x:String> </GridView>
HyperlinkButton
HyperlinkButton既可以作为Button来用,也可以用来做超链接。<HyperlinkButton Content="NoMasp--CSDN" NavigateUri="http://blog.csdn.net/nomasp" />
ProgressBar
相信大家都挺喜欢玩进度条的吧?我本人倒是觉得相比于Win7及Vista等,Win8的进度条变得更加有意思了。<ProgressBar x:Name="progressBar1" IsIndeterminate="True" Width="100" Margin="607,377,659,385"/> <ProgressBar x:Name="progressBar2" Value="70 " Width="100" Margin="607,352,659,410"/>
第一个图是运行中的进度条啦;第二个图中的上图也就是progressBar1,其Value为70的确定进度的进度条,下图则是progressBar2,是运行中的进度条在设计器中的静止状态。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/f1b9b05496908759cd0130841e2dd4e0.jpg)
ProgressRing
环形的进度条会不会更好玩呢?<ProgressRing x:Name="progressRing1" IsActive="True" />
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/6e6aea9b35c4e683f2b1126dcf0e1524.jpg)
Slider
比如说win8上的音量呀、屏幕亮度呀,这些地方都用到了滑动条。这里来看看它的ThumbToolTipValueConverter属性吧。为了将值绑定到Slider上,我们需要有一个类,这个类需要一个为数据绑定提供值转换的接口。可视化元素也就是Slider为绑定目标,其有2个方向:数据源->数据->绑定目标,绑定目标->数据->数据源。我们需要写一个类,可以直接在MainPage.xaml.cs下写,但更好是单独新建一个类,再考虑到这个是通用应用,所以将类新建到Shared下比较合适。
public class ThumbToolTipValueConverter : Windows.UI.Xaml.Data.IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { if(value is double) { double dValue= System.Convert.ToDouble(value); return dValue; } return null; } public object ConvertBack(object value, Type targetType, object parameter, string language) { return null; } }
然后添加以下代码作为本地实例化的资源即可。
<Page.Resources> <local:ThumbToolTipValueConverter x:Key="thumbToolTipValueC"/> </Page.Resources>
最后就是传说中的本体啦。
<Slider Width="200" Height="50" Name="slider1" ThumbToolTipValueConverter="{StaticResource thumbToolTipValueC}" />
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/aabf834818ae9d82070e333157852400.jpg)
我们还可以添加一个Button和TextBlock,让点击来在TextBlock上显示Slider的Value。
private void btnGetSliderValue_Click(object sender, RoutedEventArgs e) { tblockSlider.Text = slider1.Value.ToString(); }
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/5d7ba4818c26fbd4bdc6410c43193a62.jpg)
用浮出控件做预览效果
在前面学习控件的时候,我们已经见过了MessageDialog了,关于Button还有一个浮出控件Flyout哦。具体是怎样用呢?接下来就一起看看。我们还是延续前面的那个示例好了,那么,代码来了。
<Button x:Name="btnWhat" Content="这是什么?"> <Button.Flyout> <Flyout> <StackPanel> <TextBlock Width="430" Style="{StaticResource BaseTextBlockStyle}" Text="噢!你刚刚又踩到地雷了,要撤销吗?" Foreground="Red" FontSize="25"/> <Button Click="btnUndo_Click" Margin="12" Content="撤销"/> </StackPanel> </Flyout> </Button.Flyout> </Button>
当我们点击了撤销按钮后,当然需要btnWhat按钮的Flyout消失掉,这个嘛,也只要1行代码啦。另外这个踩雷的逻辑这里就不展开啦.
private void btnUndo_Click(object sender, RoutedEventArgs e) { btnWhat.Flyout.Hide(); }
更为重要的是在于这些在WP8上也是通用的,这才是核心所在。既然这一篇教程主要是浮出控件,如果可以借助浮出产生预览图像的效果会不会很棒呢?先来看张运行截图吧。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/af22eff331d034cbc2a426790e3bdebe.jpg)
以下都是代码啦,什么Binding呀之类的都不用管啦。需要注意的地方也就是那些Height和Width可能需要拿来调整一下。
<Page.Resources> <Flyout x:Key="ResourceFlyoutImage" Placement="Right"> <Image Source="{Binding Path=Source}" MaxHeight="800" MaxWidth="1400" Stretch="Uniform"/> <Flyout.FlyoutPresenterStyle> <Style TargetType="FlyoutPresenter"> <Setter Property="MinHeight" Value="900"/> <Setter Property="MinWidth" Value="1600"/> <Setter Property="BorderThickness" Value="3"/> <Setter Property="Background" Value="Wheat"/> <Setter Property="BorderBrush" Value="Green"/> <Setter Property="ScrollViewer.ZoomMode" Value="Enabled"/> </Style> </Flyout.FlyoutPresenterStyle> </Flyout> </Page.Resources> <Grid> <StackPanel HorizontalAlignment="Left" Orientation="Vertical"> <Image Source="Assets/14152.jpg" Width="100" Height="100" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> <Image Source="Assets/14158.jpg" Width="100" Height="100" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> <Image Source="Assets/14160.jpg" Width="100" Height="100" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> <Image Source="Assets/14164.jpg" Width="100" Height="100" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> </StackPanel> </Grid>
private void img_Tapped(object sender, TappedRoutedEventArgs e) { FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender); }
同样的,在WP上也是可以得哦,一下是做了些修改后的XAML代码啦。正如大家所见,我把图片都缩小了,Placement也设置成了Top,StactPanel的属性也做了修改。
<Page.Resources> <Flyout x:Key="ResourceFlyoutImage" Placement="Top"> <Image Source="{Binding Path=Source}" MaxHeight="600" MaxWidth="400" Stretch="Uniform"/> <Flyout.FlyoutPresenterStyle> <Style TargetType="FlyoutPresenter"> <Setter Property="MinHeight" Value="600"/> <Setter Property="MinWidth" Value="400"/> <Setter Property="BorderThickness" Value="3"/> <Setter Property="Background" Value="Wheat"/> <Setter Property="BorderBrush" Value="Green"/> <Setter Property="ScrollViewer.ZoomMode" Value="Enabled"/> </Style> </Flyout.FlyoutPresenterStyle> </Flyout> </Page.Resources> <Grid> <StackPanel VerticalAlignment="Bottom" Orientation="Horizontal"> <Image Source="Assets/14152.jpg" Width="72" Height="60" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> <Image Source="Assets/14158.jpg" Width="72" Height="60" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> <Image Source="Assets/14160.jpg" Width="72" Height="60" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> <Image Source="Assets/14164.jpg" Width="72" Height="60" Margin="12" Tapped="img_Tapped" FlyoutBase.AttachedFlyout="{StaticResource ResourceFlyoutImage}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/> </StackPanel> </Grid>
看样子效果还不错嘛。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/572345242c921e990d2dc3d27a1eae59.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/31e3bce740036ead0b22c49ebb0f0a2b.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/a32a0250b9fbe44d25540bcfd90ed194.jpg)
时间控件的更多介绍
在前面我们走马观花地介绍了一大堆控件,其中自然也包括这DatePicker和TimePicker,那么稍微高级些的用法呢?如果你想做一个关于健身、闹钟等的App,那么不可避免的会用到时间这些控件了。
<DatePicker x:Name="datePicker" Header="NoMasp Date" Foreground="Beige"/> <Button x:Name="btnOK" Click="btnOK_Click" Content="确定" Foreground="Cyan" Margin= "292,378,0,352" > <Button.Flyout> <Flyout> <TextBlock x:Name="tblock1" Foreground="Fuchsia"/> </Flyout> </Button.Flyout> </Button>
那么我们可能需要所选定的时间是未来时间,也就是比应用运行时的时间要大。获取当前选中的时间给程序的其他部分使用也是很简单的,我这里的year等都在之前定义过了哦,在函数内定义可是不明智的哟。
private void btnOK_Click(object sender, RoutedEventArgs e) { if(datePicker.Date>DateTimeOffset.Now) tblock1.Text = string.Format("你所选中的时间是:{0}。", datePicker.Date.ToString("D")); else tblock1.Text = "噢!你想要穿越吗?"; year = datePicker.Date.Year; month = datePicker.Date.Month; day = datePicker.Date.Day; }
有意思的事情又来了,如果你是想要做一个时间囊,默认的时间就是10年之后,那么DatePicker的初始事件如果正好就是10年后不是非常好吗。那么我们要做的呢,首先就是给DatePicker的Loaded写一条事件啦。(虽然我觉得App是保存不了10年的)
private void datePicker_Loaded(object sender, RoutedEventArgs e) { datePicker.Date = DateTimeOffset.Now.AddYears(10); }
如果不想兴师动众去用DatePicker的Loaded,那么也可以直接在后台代码中这样写。
protected override void OnNavigatedTo(NavigationEventArgs e) { datePicker.Date = DateTimeOffset.Now.AddYears(10); }
我还做了一个小测试呢,在Loaded事件中让时间增加11年,在OnNavigatedTo事件中让时间增加10年,结果——结果是增加了11年啦,看来还是自家的Loaded更厉害。
接下来就是TimePicker啦,回到健身的话题,假设哈,6点到18点才适合运动,那么我们的Microsoft Band就做了以下这么个要求(开玩笑啦)。
private void btnOK_Click(object sender, RoutedEventArgs e) { TimeSpan startTime = new TimeSpan(6, 0, 0); TimeSpan endTime = new TimeSpan(18, 0, 0); if(timePicker.Time>=startTime&&timePicker.Time<=endTime) { tblock1.Text = string.Format("这段时间运动都是很好的哦——{0}。", timePicker.Time.ToString()); } else { tblock1.Text = "此时间吧不适合运动的吧?"; } }
也许你还想控制手环上时间选择器的初始时间,那么代码来了。
protected override void OnNavigatedTo(NavigationEventArgs e) { timePicker.Time = new TimeSpan(23, 0, 0); }
作为强迫症患者呢,每次我设定闹钟的时候都要设置在一个比较好的时间,比如被5整除啦、质数啦。这里可以用MinuteIncrement属性来控制分钟的增量哟,比如增量为5呀。从小学起就飞得把电子手表的时间给设置成24小时制的,这个也是可以实现的,ClockIdentifier设置成24HourClock就搞定啦。
应用栏
基本的用法我们在教程前面的“页面布局与基本导航”中已经讲过了,这里继续补充关于应用栏的更多用法。Icon
在之前的学习中,我们知道Icon属性中有很多很多系统预定义,但也许这些还是不够的,现在就来增加几种用法。字符集应用
<AppBarToggleButton Label="Sigma" Click="AppBarButton_Click"> <AppBarToggleButton.Icon> <FontIcon Glyph="Σ"/> </AppBarToggleButton.Icon> </AppBarToggleButton>
关于更多字符集的应用请访问维基百科。
PathIcon
我们也可以用路径来绘制一个属于自己的图形哦,下面的图形大概就是9点钟的样子啦。
<AppBarToggleButton Label="Time" Click="AppBarButton_Click"> <AppBarToggleButton.Icon> <PathIcon Data="F1 M 20,20 21,1L 21,21L 8,21"/> </AppBarToggleButton.Icon> </AppBarToggleButton>
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/f2d75cf106c157d5580f22a308f80b79.jpg)
如何适应不同的分辨率
如何适应不同的分辨率这也是值得我们去解决的问题,毕竟不论是从8英寸的平板还是25英寸的台式机,甚至还有4英寸至7英寸的手机,在应用栏按钮太多而屏幕不够大时,多余的按钮该怎么办呢?默认情况下,应用栏图标的宽度都是确定好的100像素哦。那么我们先来看两张图片好了,由于Windows 10是可以直接调整Modern应用的大小的(而不是windows 8那种只能全屏显示),所以我直接拉伸Modern大小以模拟分辨率的概率啦。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/69b609d50c0ad9268aaf169e9160ff10.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/2d709a1b015fbd1f8d0f8dea1afd3641.jpg)
<Page.BottomAppBar> <AppBar x:Name="bottomAppBar" IsSticky="True"> <Grid> <StackPanel x:Name="leftBottomAppBar" Orientation="Horizontal"> <AppBarButton Label="Like" Icon="Like"/> <AppBarButton Label="Dislike" Icon="Dislike"/> <AppBarButton Label="Delete" Icon="Delete"/> <AppBarButton Label="Download" Icon="Download"/> <AppBarButton Label="Pin" Icon="Pin"/> </StackPanel> <StackPanel x:Name="rightBottomAppBar" Orientation="Horizontal" HorizontalAlignment="Right"> <AppBarButton Label="Play" Icon="Play"/> <AppBarButton Label="Pause" Icon="Pause"/> <AppBarButton Label="Stop" Icon="Stop"/> <AppBarButton Label="Previous" Icon="Previous"/> <AppBarButton Label="Next" Icon="Next"/> </StackPanel> </Grid> </AppBar> </Page.BottomAppBar>
这里为了调试更加方便,所以使用了IsSticky属性。AppBarButton还有一个很重要的属性哟,之前用不到,不过这里就是核心成员了呢,它就是IsCompact。这个属性可以让应用栏按钮只显示图标而不显示文字,也就是Label啦。那么我们的工作就要围绕这个属性来展开了。
我们可以这样假设,有一个函数,它有一个布尔变量的参数,参数为真的话呢,那么所有的这些AppBarButton的IsCompact属性也为真。在以下这段代码中,我们先将bottomAppBar的自对象选取为root,这样一来的话呢,如果应用中还有顶部的应用栏,就不会相互干扰啦。然后逐步取出root和panel中的自对象就好咯。
private void AppBarButtonCompact(bool isCompact) { Panel root = bottomAppBar.Content as Panel; if(root!=null) { foreach(Panel panel in root.Children) { foreach (ICommandBarElement child in panel.Children) { child.IsCompact = isCompact; } } } }
接下来还需要判断到底需不需要启用IsCompact,那这又是由什么决定的呢,既然前面提到是因为屏幕的分辨率,也就是所应用所占用的宽度会导致应用栏发生重叠,那么答案就毫无疑问了。看到下面的代码相信大家都明白了,至于为何是宽度的界限在1000呢,那是因为有10个AppBarButton,前面也说了它们的宽度是100。(不带Label的话呢,就只需要60像素啦。)
void AppSizeChanged(object sender, SizeChangedEventArgs e) { if (e.NewSize.Width != e.PreviousSize.Width) { if (e.NewSize.Width < 1000) { AppBarButtonCompact(true); } else { AppBarButtonCompact(false); } } }
来张图片以示搞定这个问题了吧。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/15151d7510e52cbc40c66d8436710ad1.jpg)
但是像我这么钻牛角尖的人,10个AppBarButton用这种方式搞定了,那20个呢?我们就来演示一下,把之前XAML中的AppBarButton复制粘贴一番。如果是2K、4K的屏幕应对20个没问题啊,但我这1920X1080的屏幕就放不下了。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/f7128880288679796cf69da82c71a0c4.jpg)
那么这又有什么办法可以解决的吗?当然有啦,将这20个图标切成2列就好啦。我们首先在Grid中添加一行。
<Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions>
再通过下面这张方式来调整它处于哪一行,以及在水平方向的右侧还是左侧。这里我将两行都设置在右侧啦。
leftBottomAppBar.SetValue(Grid.RowProperty, 1); leftBottomAppBar.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Right);
当然了,这样一来就可以放40个AppBarButton啦,如果缩小应用的大小的话为了容纳更多还可以用IsCompact属性呢。不过没有哪个应用做成这样吧。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/53dbb4b3380811be0046a867c22addd7.jpg)
另外呢,如果把应用栏设计成这样的话。
<Page.BottomAppBar> <AppBar x:Name="bottomAppBar" IsSticky="True"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <StackPanel Grid.Column="0" x:Name="leftBottomAppBar" Orientation="Horizontal" HorizontalAlignment="Left"> <AppBarButton Label="Like" Icon="Like"/> <AppBarButton Label="Dislike" Icon="Dislike"/> <AppBarButton Label="Delete" Icon="Delete"/> <AppBarButton Label="Download" Icon="Download"/> <AppBarButton Label="Pin" Icon="Pin"/> </StackPanel> <StackPanel Grid.Column="1" x:Name="rightBottomAppBar" Orientation="Horizontal" HorizontalAlignment="Right"> <AppBarButton Label="Play" Icon="Play"/> <AppBarButton Label="Pause" Icon="Pause"/> <AppBarButton Label="Stop" Icon="Stop"/> <AppBarButton Label="Previous" Icon="Previous"/> <AppBarButton Label="Next" Icon="Next"/> </StackPanel> </Grid> </AppBar> </Page.BottomAppBar>
那么对于Windows 10,在拉伸的过程中,中间部分的控件就会慢慢消失啦。以下这张图片呢,是我在拉伸到中间有2个控件刚好重叠的时候啦。至于把AppBarButton设计成这样是好是坏大家自己决定咯,我反正觉得这样不好呢。不过有意思的是,即便如此,它们彼此的Click事件还都是有效的噢,会区分左右两部分,而不会叠在一起。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/22/d8b5d5a5cef366a1b51226116f38f33f.jpg)
当然啦,这个的应用远不是应用栏这么简单哟,对于其他的前景,比如有两个TextBlock在屏幕左右两侧,当应用把收缩变小之后也可以让这个TextBlock叠成2层在屏幕的一边。
在应用栏上添加菜单
我们都见过有菜单的应用栏按钮对吧,这个的实现其实也挺简单的。用Flyout属性就好了。<Page.BottomAppBar> <CommandBar> <AppBarButton Icon="Rotate" Label="Rotate"> <AppBarButton.Flyout> <MenuFlyout> <MenuFlyoutItem Text="Rotate 90" Click="MenuFlyoutItem_Click" Tag="Rotate90"/> <MenuFlyoutItem Text="Rotate 180" Click="MenuFlyoutItem_Click" Tag="Rotate180"/> <MenuFlyoutItem Text="Rotate 270" Click="MenuFlyoutItem_Click" Tag="Rotate270"/> </MenuFlyout> </AppBarButton.Flyout> </AppBarButton> </CommandBar> </Page.BottomAppBar>
Tag属性,就相当于做一个标签。下面这段代码就让Flyout菜单发挥作用了。
private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e) { MenuFlyoutItem selectedItem = sender as MenuFlyoutItem; if (selectedItem != null) { if (selectedItem.Tag.ToString() == "Rotate90") { DoRotate(90); } else if (selectedItem.Tag.ToString() == "Rotate180") { DoRotate(180); } else if (selectedItem.Tag.ToString() == "Rotate270") { DoRotate(270); } } }
版权声明:本文为 NoMasp柯于旺 原创文章,未经许可严禁转载!欢迎访问我的博客:http://blog.csdn.net/nomasp
相关文章推荐
- 如何成为一名专家级的开发人员
- 一步一步跟我学易语言之第二个易程序菜单设计
- flex 控件的重要属性
- Delphi控件ListView的属性及使用方法详解
- web下载的ActiveX控件自动更新
- WinForm实现按名称递归查找控件的方法
- 基于逻辑运算的简单权限系统(原理,设计,实现) VBS 版
- C#中父窗口和子窗口之间控件互操作实例
- C#中设计、使用Fluent API
- MFC中动态创建控件以及事件响应实现方法
- WinForm自定义函数FindControl实现按名称查找控件
- 基于逻辑运算的简单权限系统(原理,设计,实现) VBS 版
- WinForm拖拽控件生成副本的解决方法
- .NET微信公众号开发之公众号消息处理
- ASP.NET动态添加用户控件的方法
- ASP.NET的HtmlForm控件学习及Post与Get的区别概述
- WinForm实现移除控件某个事件的方法
- 使用nodejs开发cli项目实例
- JavaScript 组件之旅(一)分析和设计
- C#分屏控件用法实例