注:本系列学习帖子我在DevDiv.com移动开发社区原创首发
转载请注明出处:BeyondVincent(破船)@DevDiv.com
如果你有什么问题也可以前往交流
下面是首发地址:
[DevDiv原创]Windows 8 Metro App开发Step by Step---(13个学习帖子)
有时候在程序中,我们需要弹出一个画面与用户进行交互,此时我们并不想从当前画面切走,那是针对这种情况使用弹出画面(Flayouts)是比较好的一种选择。今天我就带领大家一起学习一下如何在程序画面中弹出一个画面。主要功能实现:当用户点击AppBar中的某个按钮时,弹出一个画面,达到与用户交互的目的。
弹出画面是一个pop-up窗口,显示在被点击按钮附近,当用户点击或者触摸屏幕的非弹出画面区域时,弹出画面会自动的消失。
通过本次学习,你将掌握以下内容:
1、创建自定义控件
2、编写自定义控件代码
3、定位弹出的控件(画面)
4、在程序中使用弹出画面
5、显示弹出画面
6、最后附上程序运行截图和程序demo
[注:本次使用的代码从这个帖子给出的demo继续编码
Windows 8 Metro App开发之应用程序栏(AppBar)的使用
更多内容请查看下面的帖子
1、创建自定义控件
为了代码易于管理,在这里,我把弹出画面定义为一个自定义控件。也就是包含一个xaml文件和相关的代码文件。如下图所示,如何创建自定义控件:
选择用户控件,输入名称就可以了。
下图是创建好的画面
我将控件文件SearchFlayout存放在Flayouts文件夹下。
在xaml文件中添加如下代码
<UserControl
x:Class="DevDiv_AppBar.Flayouts.SearchFlayout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DevDiv_AppBar.Flayouts"
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="400">
<Grid>
<Popup x:Name="SearchPopup" IsLightDismissEnabled="True" Width="350" Height="130" >
<StackPanel Background="Black">
<Border Background="#85bd" BorderThickness="4">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="请输入搜索内容:" VerticalAlignment="Center" Margin="0,0,10,0" />
<TextBox Name="searchDataBox" Height="40" Width="150" FontSize="20" />
</StackPanel>
<Button Click="SearchButtonClick" HorizontalAlignment="Center" Margin="10">搜索</Button>
</StackPanel>
</Border>
</StackPanel>
</Popup>
</Grid>
</UserControl>
在代码中,需要提醒的是Popup的属性IsLightDismissEnabled="True"。这表示当用户点击或者触摸屏幕的任意位置,不包括Popup的位置,pop-up画面是否消失。当把Popup用作弹出画面时,这个属性必须设置为True,因为这是才符合基本的弹出画面(flyout)用户体验。
如下图所示,我们还可以在设计器中,看到自定义控件长什么样
在上面的代码中需要注意的是创建弹出画面必须使用Popup控件,至于Popup控件里面的内容就按需而定即可。我在这里用了TextBlock、TextBox和Button三个控件,当然还有一个StackPanel容器控件。

这样我们xaml文件就基本写完了。下面我们开始编写控件的C#代码
2、编写自定义控件代码
在这里,自定义控件中主要实现两个功能:显示控件本身和响应控件提供的相关用户交互操作 大家看下面两个函数Show方法主要就是将自己显示出来。SearchButtonClick是响应自定义控件中的搜索按钮事件。
注意:在Show方法中有一行代码如下,是用来计算当前弹出画面需要显示的位置,后面会有讲解(由于目前的版本中微软并没有提供相关好的方法来获取显示的位置,所以需要自行计算,希望在windows 8正式版发布之后,能解决这个问题)
FlyoutHelper.ShowRelativeToAppBar(SearchPopup, page, appbar, button);
public void Show(Page page, AppBar appbar, Button button)
{
SearchPopup.IsOpen = true;
FlyoutHelper.ShowRelativeToAppBar(SearchPopup, page, appbar, button);
}
private void SearchButtonClick(object sender, RoutedEventArgs e)
{
SearchPopup.IsOpen = false;
}
3、定位弹出的控件(画面)
在这里我创建了一个FlyoutHelper类,其中定义了一个静态方法ShowRelativeToAppBar。这个方法计算出相关按钮上显示的Popup的正确位置,这样做,需要传入Popup控件、包含AppBar的Page、AppBar控件和被点击的button按钮。这个方法并不好,但这是我发现的可以获得flyout准确位置的唯一方法。具体代码如下:
namespace DevDiv_AppBar.Flayouts
{
class FlyoutHelper
{
public static void ShowRelativeToAppBar(Popup popup, Page page, AppBar appbar, Button button)
{
Func<UIElement, UIElement, Point> getOffset = delegate(UIElement control1, UIElement control2)
{
return control1.TransformToVisual(control2).TransformPoint(new Point(0, 0));
};
Point popupOffset = getOffset(popup, page);
Point buttonOffset = 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;
}
else if
(popup.HorizontalOffset + popupOffset.X < 0)
{
popup.HorizontalOffset = -popupOffset.X;
}
}
}
}
4、在程序中使用弹出画面
将刚刚定义的控件添加到MainPage.xaml中,代码如下所示。
这里需要将名称空间添加进来using:DevDiv_AppBar.Flayouts 这样才能使用Flayouts中定义的控件。
下面的代码中,添加自定义控件是这行代码
<flyouts:SearchFlayout x:Name="SearchFlayout"/>
虽然这里并不是马上就显示出弹出画面,但是我们也需要把自定义控件声明为主程序布局的一部分。
<Page
x:Class="DevDiv_AppBar.MainPage"
IsTabStop="false"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DevDiv_AppBar"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:flyouts="using:DevDiv_AppBar.Flayouts"
mc:Ignorable="d">
<Grid Background ="PaleGoldenrod">
<Image HorizontalAlignment="Left" Height="200" Margin="495,215,0,0" VerticalAlignment="Top" Width="295" Source="Assets/icon.png"/>
<flyouts:SearchFlayout x:Name="SearchFlayout"/>
</Grid>
</Page>
5、显示弹出画面
现在代码基本编写完毕了,剩下的任务就是当用户点击AppBar上的搜索按钮时,将弹出画面显示出来即可。
我在MainPage.xaml.cs中添加如下代码:
并将该方法与AppBar的搜索按钮Click事件关联起来即可
private void AppBarButtonClick(object sender, RoutedEventArgs e){
if (e.OriginalSource == AppBarSearchButton)
{
SearchFlayout.Show(this, this.BottomAppBar, (Button)e.OriginalSource);
}
}
6、最后附上程序运行截图和程序demo

代码下载
