鸟叔学Windows8开发(1):自定义弹出窗口

摘要:
因为鸟叔在添加三个以上的命令时报告了一个异常(=null)pop。IsOpen=false;}}步骤2:添加用户控件:用于在弹出框中显示内容。这里我们创建一个用户登录界面。

哦把橄榄石带偶。。。。。先声明下下,接下来将要写的一些关于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();
        }

鸟叔学Windows8开发(1):自定义弹出窗口第1张

大家可能注意到代码中出现了两个新的关键字: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、并且设置窗口透明度。

第一步:先创建一个模版控件:作为弹出窗的模版以后可以共用

鸟叔学Windows8开发(1):自定义弹出窗口第2张

然后VS自动给我们创建了一个Themes文件夹并且在下面创建了一个Generic.xaml(是一个资源字典文件)文件

鸟叔学Windows8开发(1):自定义弹出窗口第3张

在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>

 同时还有一个关联的后台代码文件(生成的名称和自己定义的一样)

鸟叔学Windows8开发(1):自定义弹出窗口第4张

添加如下后台代码

 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;
        }
    }

第二步:添加一个用户控件:用于在弹出框中显示的内容,这里我们创建一个用户登录的界面。

鸟叔学Windows8开发(1):自定义弹出窗口第5张

 前台代码:

<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();
        }

效果:

鸟叔学Windows8开发(1):自定义弹出窗口第6张

接下来一同与鸟叔来学习下这个过程:

创建模版控件——〉创建用户控件并且赋值给模版空间——〉显示

在这个简单的过程中鸟叔又很多疑问????

1、在创建模版控件的时候我们在Generic.xaml中定义的style怎么关联到我们的控件上面的?

    在Generic.xaml和后台代码文件PopupsControl.cs中鸟叔发现并没有显示引用style的迹象。

例如我们在一个页面的Resources中定义的style需要我们定义Key(当我们定义key的时候我们必须在控件中显示引用才能有效果)或者不定义(这时候叫做类型样式,页面用的所有被样式作为目标的空间的样式都会改变,即使我们在控件中没有显示的引用)。大家跟着鸟叔看下上面的MyUserControl1.xaml中我的一段注释代码:

鸟叔学Windows8开发(1):自定义弹出窗口第7张

大家自己试试给style设置和不设置Key的效果,就会明白了。具体大家也可以多查下关于WPF/Silverlight样式方面的资料。

说了这么多好像没有回答我们的问题。因为我们需要显示样式中定义的效果的时候,我们需要显示应用或者使用类型样式。但是我们在定义模版控件的时候不管我们设不设置Key我们的模版控件都会引用该样式。

这时为什么呢 为什么呢,,,鸟叔最后发现当我们创建模版控件的时候VS会自动给我生成一个东东:

鸟叔学Windows8开发(1):自定义弹出窗口第8张

原来就是这个东西在作怪,鸟叔就是一个不淡定的人,鸟叔做了一件事情:帮文件夹名称或者文件名称改变的时候,发现我们的弹出框不能使用该样式了。鸟叔估计这个是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

欢迎与鸟叔一起探讨学习,共同成长,鸟叔的微博 多了特

 

免责声明:文章转载自《鸟叔学Windows8开发(1):自定义弹出窗口》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇java实现POP3邮件客户端UE4 Subsystems下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

ssh登录时在参数中加入密码的解决方案

在使用ssh登录远程服务器的时候,在执行完sshuser@ip后,要输入登录密码,有时候登录密码记不住,这样以来Ian带来的很多的麻烦,有没有一种在ssh的参数中直接加入密码的方法呢?查看ssh的帮助我们发现ssh命令并不能在参数中制定密码。usage:ssh[-1246AaCfGgKkMNnqsTtVvXxYy][-bbind_address][-ccip...

JavaScript算法学习:获取字符串最后一位方法及判断是否以指定字符串开始或结尾

Str.substr,其中start是必需的参数,表示坐标的起始位置。正值在正方向计数,负值在反方向计数,长度是可选参数,表示从起始位置开始计数的数字。...

neo4j修改密码

输入neo4j提供的可视界面,并输入::serverchange密码。键入原始密码和新密码以修改浏览器。在系统数据库(:usesystem)中,执行以下命令ALTERUSERneo4jSETPASSWORD“mynewpass”:;...

iphone的mov文件复制到电脑的方法

解决方案:1.对于iPhone-˃设置-˃照片,将底部选项“传输到MAC或PC”从“自动”更改为“保持原始”。...

H3C交换机如何配置管理VLAN

1.输入“系统视图”(缩写为“sys”)进入系统配置模式[H3C]...

windows下如何查看和修改MySQL的端口号

更改为要设置的新端口号。4.在桌面上找到“我的电脑”,右键单击并选择“管理”5.找到“服务和应用程序”并双击6.继续双击“服务”7.在列表中找到“MySQL”,右击并选择“重新启动”8.等待重新启动完成,然后按照我们刚才用来查看MySQL端口号的方法查看更改是否成功。如图所示,3396是我更改的端口号。...