您的位置:首页 > 其它

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

2012-12-06 10:35 337 查看
这节,有三个议程①定位控件②显示用户控件③将用户控件添加到项目中

(1)定位控件

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

usingSystem;
usingWindows.Foundation;
usingWindows.UI.Xaml;
usingWindows.UI.Xaml.Controls;
usingWindows.UI.Xaml.Controls.Primitives;
namespaceMetroGrocer.Flyouts{
publicclassFlyoutHelper{
publicstaticvoid
//显示控件的相对定位的方法
//通过一个相应的代理来解决的
//计算的思路是计算前后左右的距离

ShowRelativeToAppBar(Popuppopup,Pagepage,
AppBarappbar,Buttonbutton){
Func<UIElement,UIElement,Point>getOffset=
delegate(UIElementcontrol1,UIElementcontrol2){
returncontrol1.TransformToVisual(control2)
.TransformPoint(newPoint(0,0));
};
PointpopupOffset=getOffset(popup,page);
PointbuttonOffset=getOffset(button,page);
popup.HorizontalOffset=buttonOffset.X-popupOffset.X
-(popup.ActualWidth/2)+(button.ActualWidth/2);
popup.VerticalOffset=getOffset(appbar,page).Y
-popupOffset.Y-popup.ActualHeight;
if(popupOffset.X+popup.HorizontalOffset
+popup.ActualWidth>page.ActualWidth){
popup.HorizontalOffset=page.ActualWidth
-popupOffset.X-popup.ActualWidth;
}elseif(popup.HorizontalOffset+popupOffset.X<0){
popup.HorizontalOffset=-popupOffset.X;
}
}
}
}


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

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


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

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

<!--数据绑定方式显示弹出的形式-->
<TextBoxHeight="40"Width="150"Text="{BindingPath=HomeZipCode,Mode=TwoWay}"/>


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

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

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

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

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

<!--flyouts所在的命名空间-->
<Page
x:Class="MetroGrocer.Pages.ListPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MetroGrocer.Pages"
xmlns:flyouts="using:MetroGrocer.Flyouts"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<GridBackground="{StaticResourceAppBackgroundColor}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanelGrid.RowSpan="2">
//…contentsremovedforbrevity
</StackPanel>
<StackPanelOrientation="Vertical"Grid.Column="1">
//…contentsremovedforbrevity
</StackPanel>
<StackPanelOrientation="Vertical"Grid.Column="1"Grid.Row="1">
//…contentsremovedforbrevity
</StackPanel>
<!--导入的用户控件-->
<flyouts:HomeZipCodeFlyoutx:Name="HomeZipFlyout"/>
</Grid>
<Page.BottomAppBar>
//…contentsremovedforbrevity
</Page.BottomAppBar>
</Page>


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

xmlns:flyouts="using:MetroGrocer.Flyouts"


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

<flyouts:HomeZipCodeFlyoutx:Name="HomeZipFlyout"/>


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

哝——这样一个控件就能添加到项目中了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: