哦把橄榄石带偶。。。。。先声明下下,接下来将要写的一些关于Win8开发文章可能有些代码和网上一些博客的代码基本一致(哈哈大家一起借鉴学习,但是鸟叔表示在学习的过程中坚持原创),代码相像归相像,最重要的是要举一反三,刨根问底,弄清原理。要有鸟叔的思想。。。。。
一、默认弹出框MessageDialog
1、在学习自定义弹出窗口之前先学习下,WIN8自带的弹出窗口,直接上代码,然后分析下。
async protected void onOKClick(object sender, RoutedEventArgs e) { //第一步:先声明MessageDialog MessageDialog msgOne = new MessageDialog("弹出一个按钮"); //第二步:给弹出框添加命令并添加处理方法 msgOne.Commands.Add(new UICommand("确定", new UICommandInvokedHandler(OnUICommand))); //第三步:显示弹出框 await msgOne.ShowAsync(); }
大家可能注意到代码中出现了两个新的关键字:async和await,这是.NET4.5中为了处理异步操作更象同步操作代码而加入的,呵呵 好像有点没说清,具体大家可以去问MSDN。。。
2、给弹出框添加多个命令和设置默认按钮命令索引
//添加多个命令 msgThree.Commands.Add(new UICommand("重试", new UICommandInvokedHandler(OnUICommand))); msgThree.Commands.Add(new UICommand("忽略", new UICommandInvokedHandler(OnUICommand))); msgThree.Commands.Add(new UICommand("取消", new UICommandInvokedHandler(OnUICommand))); //msgThree.Commands.Add(new UICommand("第四个命令", new UICommandInvokedHandler(OnUICommand))); //默认按钮索引 msgThree.CancelCommandIndex = 2;//当用户按Esc键时触发这个命令 msgThree.DefaultCommandIndex = 0;//当用户按ENTER键时促发这个命令
这么简单的代码鸟叔你也敢贴上来,呵呵大家知道为什么我把第四个命令注释掉了吗?因为鸟叔在添加超过三个命令的时候程序报异常了。这微软大哥也太坑了吧。。。所以说命令最多添加三个。
同时我们可以设置按ESC和ENTER键时关联的命令。
二、自定义弹出窗
这微软大哥自带的弹出窗也太那个啥了吧,不能自定义还只能添加最多三个按钮,这对于最近比较火的鸟叔来说完全不够用呀,我要做一个用户注册或者登录框怎么办,因为鸟叔爱学习,所以想到了自定义弹出框。
原理:1、要和当前页面弹出一个和窗口大小一样的窗口(目的将下面的窗口不能使用),
2、并且设置窗口透明度。
第一步:先创建一个模版控件:作为弹出窗的模版以后可以共用
然后VS自动给我们创建了一个Themes文件夹并且在下面创建了一个Generic.xaml(是一个资源字典文件)文件
在Generic.xaml文件中添加如下代码:
<Style TargetType="local:PopupsControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:PopupsControl"> <Grid> <!--下面两个控件占有一个空间, 如果Rectangle在前面,当不设置Rectangle的Canvas.ZIndex属性或者为0时ContentPresenter不会被遮盖 如果Rectangle在后面,当设置为0的时候也会被遮盖,因为默认为0这时候就认为后面加入的在前面加入的上面 这里我们没有设置Rectangle的With和height属性,他会自动继承, 但是一些不是继承属性的时候我们需要用TemplateBinding来绑定--> <Rectangle Canvas.ZIndex="0" Fill="Black" Opacity="0.5"/> <!--TemplateBinding在一些不能继承的属性中非常有用,为了能够让模版使用控件中的属性值--> <!--ContentPresenter用于承载内容--> <ContentPresenter Content="{TemplateBinding Content}"/> <!--HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" ContentTemplate="{TemplateBinding ContentTemplate}"--> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
同时还有一个关联的后台代码文件(生成的名称和自己定义的一样)
添加如下后台代码
public class PopupsControl : ContentControl { //定义一个弹出框 Popup pop = null; public PopupsControl() { this.DefaultStyleKey = typeof(PopupsControl); this.HorizontalContentAlignment = HorizontalAlignment.Stretch; this.Width = Window.Current.Bounds.Width; this.Height = Window.Current.Bounds.Height; pop = new Popup(); this.pop.Child = this;//设置承载内容 } //这段代码没弄懂,求讲解??? public TransitionCollection PopTransitionCollection { get { if (pop.ChildTransitions == null) pop.ChildTransitions = new TransitionCollection(); return pop.ChildTransitions; } } //打开 public virtual void OpenpPop() { if (pop != null) pop.IsOpen = true; } //关闭 public virtual void ClosePop() { if (pop != null) pop.IsOpen = false; } }
第二步:添加一个用户控件:用于在弹出框中显示的内容,这里我们创建一个用户登录的界面。
前台代码:
<UserControl x:Class="_2弹出框.MyUserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:_2弹出框" 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="600"> <UserControl.Resources> <Style x:Key="MyTextBlockStyle" TargetType="TextBlock"> <Setter Property="FontSize" Value="20"/> <Setter Property="Margin" Value="5,10,0,5"/> <Setter Property="HorizontalAlignment" Value="Right"/> </Style> <Style x:Key="MyTextBoxStyle" TargetType="TextBox"> <Setter Property="FontSize" Value="20"/> <Setter Property="Margin" Value="5,8,0,5"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="Width" Value="300"/> </Style> <!--当我们没有为style设置key的时候,页面中的所有被Style定义的目标类型都将使用, 如果我们定义了Key,则要显示的引用才能使用--> <Style x:Key="ss" TargetType="Button"> <Setter Property="Foreground" Value="Red"/> </Style> </UserControl.Resources> <Grid VerticalAlignment="Center" Background="Blue"> <Grid Margin="0,60,0,30" Width="500"> <StackPanel Orientation="Vertical"> <TextBlock Text="登录" Margin="0,0,0,30" Style="{StaticResource PageHeaderTextStyle}"/> <Grid VerticalAlignment="Center"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Text="用户名:" Style="{StaticResource MyTextBlockStyle}" Grid.Column="0" Grid.Row="0"/> <TextBox Style="{StaticResource MyTextBoxStyle}" Grid.Column="1" Grid.Row="0"/> <TextBlock Text="密 码:" Style="{StaticResource MyTextBlockStyle}" Grid.Column="0" Grid.Row="1"/> <TextBox Style="{StaticResource MyTextBoxStyle}" Grid.Column="1" Grid.Row="1"/> <Button Content="登录" FontSize="20" Grid.Column="1" Grid.Row="2" Width="80" Height="45" Margin="230,0,0,0" Click="Button_Click_1"/> </Grid> </StackPanel> </Grid> </Grid> </UserControl>
后台代码:
public sealed partial class MyUserControl1 : UserControl { PopupsControl pop = null; public MyUserControl1(PopupsControl p) { this.InitializeComponent(); pop = p; } private void Button_Click_1(object sender, RoutedEventArgs e) { //关闭弹出框 if (pop != null) pop.ClosePop(); } }
第三步:显示我们的弹出窗口
protected override void OnNavigatedTo(NavigationEventArgs e) { //1、实例化弹出窗 PopupsControl pop = new PopupsControl(); MyUserControl1 uc = new MyUserControl1(pop); //2、将自定义控件赋值给弹出窗 pop.Content = uc; //3、显示 pop.OpenpPop(); }
效果:
接下来一同与鸟叔来学习下这个过程:
创建模版控件——〉创建用户控件并且赋值给模版空间——〉显示
在这个简单的过程中鸟叔又很多疑问????
1、在创建模版控件的时候我们在Generic.xaml中定义的style怎么关联到我们的控件上面的?
在Generic.xaml和后台代码文件PopupsControl.cs中鸟叔发现并没有显示引用style的迹象。
例如我们在一个页面的Resources中定义的style需要我们定义Key(当我们定义key的时候我们必须在控件中显示引用才能有效果)或者不定义(这时候叫做类型样式,页面用的所有被样式作为目标的空间的样式都会改变,即使我们在控件中没有显示的引用)。大家跟着鸟叔看下上面的MyUserControl1.xaml中我的一段注释代码:
大家自己试试给style设置和不设置Key的效果,就会明白了。具体大家也可以多查下关于WPF/Silverlight样式方面的资料。
说了这么多好像没有回答我们的问题。因为我们需要显示样式中定义的效果的时候,我们需要显示应用或者使用类型样式。但是我们在定义模版控件的时候不管我们设不设置Key我们的模版控件都会引用该样式。
这时为什么呢 为什么呢,,,鸟叔最后发现当我们创建模版控件的时候VS会自动给我生成一个东东:
原来就是这个东西在作怪,鸟叔就是一个不淡定的人,鸟叔做了一件事情:帮文件夹名称或者文件名称改变的时候,发现我们的弹出框不能使用该样式了。鸟叔估计这个是VS在后台做了些关联的是但是不知道具体是怎么关联的,希望哪位知道的帮鸟叔讲解下。
2、弹出窗是怎么弹出来的(弹弹弹 弹走鱼尾纹。。。)
a、鸟叔定义了一个Popup用来承载内容并且在当前窗口显示
b、将一个继承于ContentControl的PopupsControl赋值给Popup实例,
c、鸟叔在PopupsControl的控件模版的Style中定义了一个ControlTemplate并且设置了一个ContentPresenter(用来承载内容的)。
d、然后将用户控件赋值给PopupsControl,最后其实是借助Popup弹出来的。
总结:要真正理解弹出框我们需要学习,内容控件ContentControl、控件模版ControlTemplate,以及样式Style和资源Resource相关方面的知识。
博文参考:
http://blog.csdn.net/tcjiaan/article/details/7928040
http://blog.csdn.net/tcjiaan/article/details/8036375
欢迎与鸟叔一起探讨学习,共同成长,鸟叔的微博 多了特