手把手玩转win8开发系列课程(21)

简介:

这节,有三个议程①定位控件②显示用户控件③将用户控件添加到项目中

(1)定位控件

Metro布局控件没有提供了一种简单相对定位的布局方式,因此,在项目中你需要做一下灵活的处理了。下面就展示了我在Flyouts文件夹下写的FlyoutHelper类的情况,他定义了一个ShowRelativeToAppBar的方法。这个方法的职责是十分单一的,就是讲这个 用户控件定位到appBar Button控件旁边了。为了实现这样的效果,我们所需要的是一个popup control,一点击的这个按钮,就出现上述弹出用户控件的情况,尽管,这个方法看起来并不是那么的好了,但这也是我能解决这个问题想到的唯一的解决方法。


 1 using System;
 2 using Windows.Foundation;
 3 using Windows.UI.Xaml;
 4 using Windows.UI.Xaml.Controls;
 5 using Windows.UI.Xaml.Controls.Primitives;
 6 namespace MetroGrocer.Flyouts {
 7   public class FlyoutHelper {
 8     public static void 
 9 //显示控件的相对定位的方法
10 //通过一个相应的代理来解决的
11 //计算的思路是计算前后左右的距离
12 
13 ShowRelativeToAppBar(Popup popup, Page page,
14       AppBar appbar, Button button) {
15       Func<UIElement, UIElement, Point> getOffset =
16         delegate(UIElement control1, UIElement control2) {
17           return control1.TransformToVisual(control2)
18             .TransformPoint(new Point(0, 0));
19         };
20       Point popupOffset = getOffset(popup, page);
21       Point buttonOffset = getOffset(button, page);
22       popup.HorizontalOffset = buttonOffset.X - popupOffset.X
23         - (popup.ActualWidth / 2) + (button.ActualWidth / 2);
24       popup.VerticalOffset = getOffset(appbar, page).Y
25         - popupOffset.Y - popup.ActualHeight;
26       if (popupOffset.X + popup.HorizontalOffset
27         + popup.ActualWidth > page.ActualWidth) {
28         popup.HorizontalOffset = page.ActualWidth
29           - popupOffset.X - popup.ActualWidth;
30       } else if (popup.HorizontalOffset + popupOffset.X < 0) {
31         popup.HorizontalOffset = -popupOffset.X;
32       }
33     }
34   }
35 }

Popup的位置是出现在appBar的前面,他隐藏在屏幕的左部和右部。至于要我深入源代码的讲解的话,我看还是没有这么样必要吧,因为可能win8正式版上面,这样做的更好吧。至于,你碰到过某个问题吧,我这里告诉你他的先查相应的资料,再深挖他的实质,这是我多年来的编程经验  


ShowRelativeToAppBar方法是展示弹出窗口周围位置的对话框,这个方法就是用于判断HorizonOffset判断其中的距离,VerticalOffset判断其中的垂直的距离。这样经过一定处理,能够实现了定位了。
 


(2)展示这个弹出对话框

至于HomeZipCodeFlyout类除了展示数据以外,另外一个职责就是显示和隐藏这个弹出控件,这里有很多很多方法使其弹出吗,我这里当然是使用最简单的解决方案。下列源代码展示了一种数据绑定的方式。


1 <!--数据绑定方式显示弹出的形式-->
2 <TextBox Height="40" Width="150" Text="{Binding Path=HomeZipCode, Mode=TwoWay}" />

至于数据绑定,默认是one-way绑定,这就意味着我只能页面展示的数据随着后台数据变,反之亦然。而two-way方式,则是意味着后台数据(View Model)与前台展示互相关联、

 

特别提醒,我这里没有必要设置dataContext进行了绑定,但你一旦把这个用户控件添加到页面这种去了,由于是页面级对象,他也继承了DataContext这个属性、

言归正卷,怎么弹出隐藏控件了,隐藏此控件很好解决嘛,可以通过ok按钮的控制解决嘛。由于two-way绑定的模式,我根本不用担心数据是否保持同步的问题。当然了,不可能有事情十全十美,这么做的最大的缺点就是在控件消失前,他已经更新数据多次,影响效率,还有影响界面中另外viewmodel的界面了。但对于HomeZip这个属性,也很好,因为zip是唯一的。所以了这种方法不失为一个解决这个问题的理想方法。

(3)向程序中添加FlyOut控件

怎么将其添加到主界面上出了,你就可以用以下代码:


 1 <!--flyouts 所在的命名空间-->
 2 <Page
 3   x:Class="MetroGrocer.Pages.ListPage"
 4   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 5   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 6   xmlns:local="using:MetroGrocer.Pages"
 7 xmlns:flyouts="using:MetroGrocer.Flyouts"
 8   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 9   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
10   mc:Ignorable="d">
11   <Grid Background="{StaticResource AppBackgroundColor}">
12     <Grid.RowDefinitions>
13       <RowDefinition/>
14       <RowDefinition/>
15     </Grid.RowDefinitions>
16     <Grid.ColumnDefinitions>
17       <ColumnDefinition/>
18       <ColumnDefinition/>
19     </Grid.ColumnDefinitions>
20     <StackPanel Grid.RowSpan="2">
21       // …contents removed for brevity
22     </StackPanel>
23     <StackPanel Orientation="Vertical" Grid.Column="1">
24       // …contents removed for brevity
25     </StackPanel>
26 <StackPanel Orientation="Vertical" Grid.Column="1" Grid.Row="1">
27       // …contents removed for brevity
28     </StackPanel>
29 <!--导入的用户控件-->
30   <flyouts:HomeZipCodeFlyout x:Name="HomeZipFlyout"/>
31   </Grid>
32   <Page.BottomAppBar>
33     // …contents removed for brevity
34   </Page.BottomAppBar>
35 </Page>

在xaml中引用命名空间很简单,就像下面一样:


1 xmlns:flyouts="using:MetroGrocer.Flyouts"

最重要的,不是引用什么命名空间,而是引用命名空间以后,引用其中的用户控件,用户控件的源代码如下所示:


1 <flyouts:HomeZipCodeFlyout x:Name="HomeZipFlyout"/>

注意了,该弹出窗口是在grid控件中了,尽管他不是立马显示了,但一定布局在grid控件中了,这是一个原则,主页面才能更好控制子元素。

哝——这样一个控件就能添加到项目中了


目录
相关文章
|
10天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1210 5
|
9天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1172 87
|
9天前
|
云栖大会
阿里云云栖大会2025年9月24日开启,免费申请大会门票,速度领取~
2025云栖大会将于9月24-26日举行,官网免费预约畅享票,审核后短信通知,持证件入场
1767 12
|
19天前
|
人工智能 运维 安全
|
2天前
|
资源调度
除了nrm-pm,还有哪些工具可以管理多个包管理器的源?
除了nrm-pm,还有哪些工具可以管理多个包管理器的源?
230 127
|
10天前
|
弹性计算 Kubernetes jenkins
如何在 ECS/EKS 集群中有效使用 Jenkins
本文探讨了如何将 Jenkins 与 AWS ECS 和 EKS 集群集成,以构建高效、灵活且具备自动扩缩容能力的 CI/CD 流水线,提升软件交付效率并优化资源成本。
362 0

热门文章

最新文章