[源码下载]
作者:webabcd
介绍
重新想象 Windows 8 Store Apps 之集合控件
- ComboBox - 下拉框
- ListBox - 列表框
- FlipView - 滑动视图控件
- ItemsControl ItemsPresenter - ItemsPresenter 用来呈现 ItemsControl 的 Items
示例
1、ComboBox 的 Demo
ComboBoxDemo.xaml
x:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<StackPanel Margin="120 0 0 0">
<!--ComboBox - 下拉框-->
<!--xaml 方式为 ComboBox 添加数据-->
<ComboBox x:Name="comboBox" Width="200" Margin="5" HorizontalAlignment="Left">
<ComboBoxItem Content="ComboBoxItem1" />
<ComboBoxItem Content="ComboBoxItem2" />
<ComboBoxItem Content="ComboBoxItem3" />
</ComboBox>
<!--
后台绑定方式为 ComboBox 添加数据
DisplayMemberPath - 指定数据源中需要被显示出来的字段名称
MaxDropDownHeight - 用于指定打开后的下拉框的最大高度
-->
<ComboBox x:Name="comboBoxWithBinding" DisplayMemberPath="Name" MaxDropDownHeight="100" Width="200" Margin="5" HorizontalAlignment="Left" />
<!--通过模板设置 ComboBox 的每一项的布局和数据-->
<ComboBox ItemsSource="{Binding ItemsSource, ElementName=comboBoxWithBinding}" MaxDropDownHeight="100" Width="200" Margin="5" HorizontalAlignment="Left">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Age}" Margin="5 0 0 0" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</Grid>
</Page>
ComboBoxDemo.xaml.cs
* ComboBox - 下拉框
* IsDropDownOpen - 下拉框是否处于打开状态
* MaxDropDownHeight - 打开后的下拉框的最大高度
* DropDownOpened - 下拉框打开时触发的事件
* DropDownClosed - 下拉框关闭时触发的事件
*/
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using XamlDemo.Model;
namespace XamlDemo.Controls
{
public sealed partial class ComboBoxDemo : Page
{
public ComboBoxDemo()
{
本专题概要:
- 引言
- 如何使用平台调用Win32 函数——从实例开始
- 当调用Win32函数出错时怎么办?——获得Win32函数的错误信息
- 小结
一、引言
上一专题对.NET 互操作性做了一个全面的概括,其中讲到.NET平台下实现互操作性有三种技术——平台调用,C++ Interop和COM Interop,今天在这个专题中将会大家介绍第一种技术,即平台调用。然而朋友们应该会有这样的疑问,平台调用到底有什么用呢? 为什么我们要用平台调用的技术了?对于这两个问题的答案就是——平台调用可以帮助我们实现在.NET平台下(也就是指用C#、VB.net语言写的应用程序下)可以调用非托管函数(指定的是C/C++语言写的函数)。这样如果我们在.NET平台下实现的功能有现有的C/C++ 函数实现了这样的功能,这时候我们完全没必要自己再用托管语言(如C#、vb.net)去实现一个这样的功能,这时候我们应该想到 “拿来主义”,直接使用平台调用技术调用C/C++ 实现的函数。然而在实际应用中,使用平台调用技术来调用Win32 API较为普遍,所以在这个专题中将为大家具体介绍了如何使用平台调用来调用Win32函数以及调用过程中应该注意的问题,下面就从一个具体的实例开始本专题的介绍。
二、如何使用平台调用Win32 函数——从实例开始
在前一个专题中已经介绍了使用平台调用来调用非托管函数的步骤:
(1). 获得非托管函数的信息,即dll的名称,需要调用的非托管函数名等信息
(2). 在托管代码中对非托管函数进行声明,并且附加平台调用所需要属性
(3). 在托管代码中直接调用第二步中声明的托管函数
然而调用Win32 API函数还有一些问题需要注意的地方, 首先, 因为很多Win32 API函数都有ANSI和Unicode两个版本,所以在托管代码声明时需要指定调用调用函数的版本。 然而很多Win32 API函数有ANSI和Unicode两个版本并不是随便说说的,而是有根据的。大家从调用步骤中可以看出,第一步就需要知道非托管函数声明,为了找到需要需要调用的非托管函数,可以借助两个工具——Visual Studio自带的dumpbin.exe和depends.exe,dumpbin.exe 是一个命令行工具,可以用于查看从非托管DLL中导出的函数等信息,可以通过打开Visual Studio 2010 Command Prompt(中文版为Visual Studio 命令提示(2010)),然后切换到DLL所在的目录,输入 dummbin.exe/exports dllName, 如 dummbin.exe/exports User32.dll 来查看User32.dll中的函数声明,关于更多命令的参数可以参看MSDN; 然而 depends.exe是一个可视化界面工具,大家可以从 “VS安装目录\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\Bin\” 这个路径找到,然后双击 depends.exe 就可以出来一个可视化界面(如果某些人安装的VS没有附带这个工具,也可以从官方网站下载:http://www.dependencywalker.com/),如下图:
上图中 我用红色标示出 MessageBox 有两个版本,而MessageBoxA 代表的就是ANSI版本,而MessageBoxW 代笔的就是Unicode版本,这也是上面所说的依据。下面就看看 MessageBox的C++声明的(更多的函数的定义大家可以从MSDN中找到,这里提供MessageBox的定义在MSDN中的链接:http://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx ):
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType
);
现在已经知道了需要调用的Win32 API 函数的定义声明,下面就依据平台调用的步骤,在.NET 中实现对该非托管函数的调用,下面就看看.NET中的代码的:
// 使用平台调用技术进行互操作性之前,首先需要添加这个命名空间
using System.Runtime.InteropServices;
namespace 平台调用Demo
{
class Program
{
// 在托管代码中对非托管函数进行声明,并且附加平台调用所需要属性
// 在默认情况下,CharSet为CharSet.Ansi
// 指定调用哪个版本的方法有两种——通过DllImport属性的CharSet字段和通过EntryPoint字段指定
// 在托管函数中声明注意一定要加上 static 和extern 这两个关键字
[DllImport("user32.dll")]
public static extern int MessageBox1(IntPtr hWnd, String text, String caption, uint type);
// 在默认情况下,CharSet为CharSet.Ansi
[DllImport("user32.dll")]
public static extern int MessageBoxA(IntPtr hWnd, String text, String caption, uint type);
// 在默认情况下,CharSet为CharSet.Ansi
[DllImport("user32.dll")]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
// 第一种指定方式,通过CharSet字段指定
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox2(IntPtr hWnd, String text, String caption, uint type);
// 通过EntryPoint字段指定
[DllImport("user32.dll", EntryPoint="MessageBoxA")]
public static extern int MessageBox3(IntP