40、XAML user and custom controls
1、Using a custom UserControl:
在 XAML 中,你可以定制复杂的叫做 UserControl 的控件。通常你可以把 UserControl 创建在工程中,从而你可以
在工程中使用它,并且可以向它里面添加其他的 控件元素。例如,你可以创建一个具有特色的登录控件。你可以在一个命名
控件中定义,所以当你在 XAML 中使用它们的时候,你需要在 XAML 的根节点中使用 "xmls:my='using:MyNamespace'",
这个 “my” 是你自己定义的,映射到 “MyNamespace” 命名空间。
下面的是一个简单的 UserControl,里面有一些 text 元素,用来接收输入,点击按钮显示输出。
操作截图:
相应的 xaml :
UserControl:
<UserControl x:Class="UserAndCustomControls.BasicUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:UserAndCustomControls" 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> <StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="Your Name: " FontSize="26.667" Margin="0,0,20,0" /> <TextBox x:Name="NameInput" Width="300" /> </StackPanel> <Button Content="Click Me" Click="ClickMeButtonClicked" /> <TextBlock FontSize="53" x:Name="OutputText" /> </StackPanel> </Grid> </UserControl>
相应的 C# :
public sealed partial class BasicUserControl : UserControl { public BasicUserControl() { this.InitializeComponent(); } private void ClickMeButtonClicked(object sender, RoutedEventArgs e) { OutputText.Text = string.Format("Hello {0}", NameInput.Text); } }
在页面中引用这个控件时:
<!--在根节点添加命名空间映射--> xmlns:local="using:UserAndCustomControls" <!--在页面中,引用控件--> <local:BasicUserControl x:Name="MyHelloWorldUserControl" />
2、Creating a CustomControl:
一个用户自定义的控件可以在各种工程中使用,并且可以根据需要进行定制。用户控件一般是系统核心控件
(比如 Button)的组合。在 Visual Studio 中,你可以选择 “添加新项” 对话框中使用模板项添加一个 用户控件,
这会向工程中添加两个必要的文件: theme\generic.xaml 和 类文件。这个 “theme\generic.xaml” 文件包含
默认的样式和模板。这个路径和文件名是必须的,因此 XAML framework 将会自动加载这个控件。这个类文件包含
你的控件的逻辑。在你的类的构造函数中, 你必须设置你的 控件的 Type 为 DefaultStyleKey 的值, 这个会告诉
framework 无论何时都使用这个 style 和 template。对于命名空间的问题, custom control 和 UserControl
相同。
下面是一个很基本的例子(模板仅仅是一个 Border 元素),使用 VS 提供的控件模板创建的。
你可以看到 theme\generic.xaml 和 BasicCustomControl.cs 文件。
显示截图:
首先定义 Style 和 Template :
<Style TargetType="local:BasicCustomControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:BasicCustomControl"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
定义一个 类, 继承自 Control :
namespace UserAndCustomControls { public sealed class BasicCustomControl : Control { public BasicCustomControl() { // 获取或设置一个键,该键引用控件的默认样式。 this.DefaultStyleKey = typeof(BasicCustomControl); } } }
在其它页面引用, 首先在根元素内引用命名空间 :
xmlns:local="using:UserAndCustomControls"
在页面中添加:
<local:BasicCustomControl Width="300" Height="150" Background="Red" BorderBrush="Black" />
3、DependencyProperty :
用户控件也可以提供用户定义的属性。这可以是用户界面的属性或者在你控件中的其它任何的功能。您通常使用 DependencyProperty 实现自定义属性值,
并使用DependencyProperty。注册的方法指明依赖属性属性的名称和类型。
下面的例子是一个包含 一个label 的 Image 的用户控件。这个用户控件暴露两个依赖属性值 : ImagePath 和 Label。这个在 ImageWithLabelControl.cs
中实现的。
显示效果截图:
定义用户控件 的样式:
<Style TargetType="local:ImageWithLabelControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:ImageWithLabelControl"> <Border Background="LightBlue" BorderBrush="Black" BorderThickness="2" HorizontalAlignment="Center" Width="140" Height="150"> <StackPanel HorizontalAlignment="Center"> <!--绑定到 ImagePath 属性--> <Image Stretch="Uniform" Width="100" Height="100" Source="{TemplateBinding ImagePath}"
Margin="5" />
<!--绑定到 Label 属性--> <TextBlock TextAlignment="Center" Text="{TemplateBinding Label}"
FontFamily="Seqoe UI" FontWeight="Light" FontSize="26.667" Foreground="Black" />
</StackPanel> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
定义这个 ImageWithLabelControl 控件, 并且在 构造函数中指定 this.DefaultStyleKey 属性 :
namespace UserAndCustomControls { public sealed class ImageWithLabelControl : Control { public ImageWithLabelControl() { this.DefaultStyleKey = typeof(ImageWithLabelControl); } public ImageSource ImagePath { get { return (ImageSource)GetValue(ImagePathProperty); } set { SetValue(ImagePathProperty, value); } } public static readonly DependencyProperty ImagePathProperty = DependencyProperty.Register("ImagePath", typeof(ImageSource), typeof(ImageWithLabelControl), new PropertyMetadata(null)); public string Label { get { return (string)GetValue(LabelProperty); } set { SetValue(LabelProperty, value); } } public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(ImageWithLabelControl), new PropertyMetadata(null)); } }
引用这个控件, 首先在页面中添加 命名空间:
xmlns:local="using:UserAndCustomControls"
添加 用户控件:
<local:ImageWithLabelControl ImagePath="Assets/110Orange.png" Label="Orange" Margin="0,0,20,0" /> <local:ImageWithLabelControl ImagePath="Assets/110Strawberry.png" Label="Strawberry" />
4、Distributing your control :
为了部署一个 用户控件,从而其它的工程或者开发者可以复用它,你必须把你的控件打包到 Visual Studio Extension SDK 中。
这里有一个新的格式允许你指定你的控制支持的平台 和 依赖的资源(比如 图片,本地化内容等)必须一同打包到这个工程里。
点击下面的链接,在文档中获得更多的关于创建一个 Visual Studio 的 Extension SDK 的内容:
http://go.microsoft.com/fwlink/?LinkID=235409