简单易学 图文并茂 VB制作WPF自定义控件 范例1
vb用户控件制作讲解与实例
vb用户控件制作讲解与实例1.定义控件的属性、事件和方法,其中属性是最常使用的。
2.保存和读取中间用户设置的属性值。
3.为达到你的预定目的而调用的各种技术手段。
在用户控件中定义的属性、事件、方法,其性质都必须是公用的,也就是说,只有用Public 来定义,这样你才能在主程序代码中使用这些事件和方法,以及设置或获取这些属性值,也只有公用的属性才会在窗体页面相关控件的属性窗口显示出来。
一、属性属性是用户控件最基本的东东,用户控件可以没有事件,可以没有方法,但不能没有属性(当然,技术上来说是可以没有属性的,但这样的控件使中间用户无法进行任何设置,是没有什么意义的)。
那么,如何定义用户控件的属性呢?为用户控件添加属性有两种办法:1.公用变量法:public 变量名称as 类型这里的变量名称就是属性名称。
这样定义的属性一般不会保存属性值,所以常常用作只读属性,在笔者的用户控件中,用于对主程序返回一个必要的值。
例如“四则运算”控件中的“ComputeAnswer”属性:Public ComputeAnswer As String它返回的是计算结果,而计算结果是不需要保存在控件中的,所以把它用公用变量法定义。
再例如消息框控件中的FeedValue 属性:Public FeedValue As Integer '返回值它返回最终用户选中的消息框按纽的编号,这个编号也只需要在主程序中处理,而无需保存在控件中,所以也用公用变量法定义成只读属性。
2.property 过程法:public property Get 过程名称() as 类型……end propertypublic property Let 过程名称(new值as 类型)……end property这里的过程名称就是属性名称。
而property 过程法又有两种:一种是如上所述的标准过程法,另一种就是枚举法。
㈠标准过程法这是用得最多的一种属性定义方法。
wpf 创建用户控件实例的方法
wpf 创建用户控件实例的方法摘要:1.WPF 用户控件概述2.创建用户控件实例的方法3.用户控件的属性与事件4.实例:创建一个简单的用户控件5.总结正文:**WPF 创建用户控件实例的方法**在WPF(Windows Presentation Foundation)中,创建用户控件实例的方法有以下几种:**1.WPF 用户控件概述**WPF 用户控件是一种自定义控件,它允许开发者根据需求创建具有特定功能的控件。
用户控件可以在应用程序中重用,从而提高代码的可维护性和可读性。
**2.创建用户控件实例的方法**在WPF 项目中,创建用户控件有以下几种常用方法:(1)使用Visual Studio 创建用户控件:1.在解决方案资源管理器中,右键单击项目名称,选择“添加”>“类”。
2.在弹出的命名窗口中,输入用户控件的类名,例如“MyUserControl”。
3.在类名后添加“UserControl”,表示这是一个用户控件。
4.单击“添加”按钮,Visual Studio 会自动生成一个用户控件的基类。
(2)手动创建用户控件:1.在项目中创建一个空白用户控件(UserControl)。
2.在用户控件的代码文件中,添加所需的UI 元素和代码。
3.为UI 元素设置属性、事件处理程序等。
**3.用户控件的属性与事件**用户控件具有自己的属性、事件和方法,可以通过以下方式访问和修改:- 属性:在用户控件的代码文件中,为UI 元素添加属性,如“公共”属性。
- 事件:为UI 元素添加事件处理程序,如“单击”事件。
- 方法:在用户控件类中添加方法,以实现特定功能。
**4.实例:创建一个简单的用户控件**以下是一个简单的用户控件示例,包括一个按钮和一个文本框:```csharpusing System.Windows;using System.Windows.Media;amespace WPF_UserControl{public partial class MyUserControl : UserControl{public MyUserControl(){InitializeComponent();}public static string InputText{get { return (string)GetValue(InputTextProperty); }set { SetValue(InputTextProperty, value); }}public static readonly DependencyProperty InputTextProperty =DependencyProperty.Register("InputText",typeof(string), typeof(MyUserControl), new UIPropertyMetadata(""));private void Button_Click(object sender, RoutedEventArgs e){MessageBox.Show("输入的文本是:" + InputText);}}}```**5.总结**在WPF 中,创建用户控件实例的方法多种多样。
WPF知识点--自定义Button(ControlTemplate控件模板)
WPF知识点--⾃定义Button(ControlTemplate控件模板)ControlTemplate是⼀种控件模板,可以通过它⾃定义⼀个模板来替换掉控件的默认模板以便打造个性化的控件。
ControlTemplate包含两个重要的属性:VisualTree该模板的视觉树,⽤来描述控件的外观。
Triggers触发器列表,⾥⾯包含⼀些触发器Trigger,我们可以定制这个触发器列表来使控件对外界的刺激发⽣反应,⽐如⿏标经过时⽂本变成粗体等。
⽰例:<Window.Resources><Style TargetType="Button"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><!-- 定义视觉树 --><Grid><!-- 绘制外圆 --><Ellipse x:Name="ellipse"Width="100"Height="100"Stroke="#FF6347"><Ellipse.Fill><LinearGradientBrush StartPoint="0.5,0" EndPoint="0.443,1.22"><LinearGradientBrush.RelativeTransform><TransformGroup><ScaleTransform CenterX="0.5" CenterY="0.5"/><SkewTransform CenterX="0.5" CenterY="0.5"/><RotateTransform Angle="-50" CenterX="0.5" CenterY="0.5"/><TranslateTransform /></TransformGroup></LinearGradientBrush.RelativeTransform><GradientStop Offset="0" Color="#FF4040"/><GradientStop Offset="1" Color="White"/></LinearGradientBrush></Ellipse.Fill></Ellipse><!-- 绘制内圆 --><Ellipse Width="80"Height="80"Stroke="{x:Null}"><Ellipse.Fill><LinearGradientBrush StartPoint="0.406,1.322" EndPoint="0.563,-0.397"><LinearGradientBrush.RelativeTransform><TransformGroup><ScaleTransform CenterX="0.5"CenterY="0.5"ScaleX="-1"ScaleY="-1"/><SkewTransform AngleX="0" AngleY="0" CenterX="0.5" CenterY="0.5"/><RotateTransform Angle="-50" CenterX="0.5" CenterY="0.5"/><TranslateTransform /></TransformGroup></LinearGradientBrush.RelativeTransform><GradientStop Offset="0" Color="White"/><GradientStop Offset="1" Color="#FF4040"/></LinearGradientBrush></Ellipse.Fill></Ellipse><!-- 使⽤ContentControl或ContentPresenter重写内容 --><!--<ContentControl HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"Content="{TemplateBinding Content}" />--><ContentPresenter x:Name="contentPresenter"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Grid><!-- 定义触发器 --><ControlTemplate.Triggers><!-- 设置按钮响应事件 --><Trigger Property="IsFocused" Value="True"/><Trigger Property="IsDefaulted" Value="True"/><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="ellipse" Property="Stroke" Value="#FFFFF400"/><Setter TargetName="ellipse" Property="StrokeThickness" Value="1.5"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter TargetName="ellipse" Property="Fill"><Setter.Value><LinearGradientBrush StartPoint="0.5,0" EndPoint="0.443,1.22"><LinearGradientBrush.RelativeTransform><TransformGroup><ScaleTransform CenterX="0.5" CenterY="0.5"/><SkewTransform CenterX="0.5" CenterY="0.5"/><RotateTransform Angle="-50" CenterX="0.5" CenterY="0.5"/><TranslateTransform /></TransformGroup></LinearGradientBrush.RelativeTransform><GradientStop Offset="1" Color="#FF4040"/><GradientStop Offset="0" Color="White"/></LinearGradientBrush></Setter.Value></Setter><Setter TargetName="contentPresenter" Property="Margin" Value="5,5,0,0"/></Trigger><Trigger Property="IsEnabled" Value="False"/></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style></Window.Resources>View Code<Button Content="XButton"/>。
WPF自定义控件与样式-自定义按钮(Button)
WPF⾃定义控件与样式-⾃定义按钮(Button)⼀、前⾔程序界⾯上的按钮多种多样,常⽤的就这⼏种:普通按钮、图标按钮、⽂字按钮、图⽚⽂字混合按钮。
本⽂章记录了不同样式类型的按钮实现⽅法。
⼆、固定样式的按钮固定样式的按钮⼀般在临时使⽤时或程序的样式⽐较固定时才会使⽤,按钮整体样式不需要做⼤的改动。
2.1 普通按钮-扁平化风格先看效果:定义Button的样式,详见代码:<Style x:Key="BtnInfoStyle" TargetType="Button"><Setter Property="Width" Value="70"/><Setter Property="Height" Value="25"/><Setter Property="Foreground" Value="White"/><Setter Property="BorderThickness" Value="0"/><Setter Property="Background" Value="#43a9c7"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels <TextBlock Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="border" Property="Background" Value="#2f96b4"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter TargetName="border" Property="Background" Value="#2a89a4"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>引⽤⽅法:<Grid Background="White"><StackPanel Orientation="Horizontal" Margin="10" VerticalAlignment="Top"><Button Style="{StaticResource BtnInfoStyle}" Content="信息" Margin="5 0"/></Grid>上述代码实现了Button按钮的扁平化样式,如果你想调整颜⾊风格,通过修改Background的值可实现默认颜⾊,⿏标经过颜⾊以及⿏标按下颜⾊。
WPF控件开发之自定义控件
WPF控件开发之自定义控件Windows Presentation Foundation(WPF)控件模型的扩展性极大减少了创建新控件的需要。
但在某些情况下,仍可能需要创建自定义控件。
本主题讨论可最大限度减少在Windows Presentation Foundation(WPF)中创建自定义控件以及其他控件创作模型的需要的功能。
本主题还演示如何创建新控件。
AD:Windows Presentation Foundation(WPF)控件模型的扩展性极大减少了创建新控件的需要。
但在某些情况下,仍可能需要创建自定义控件。
本主题讨论可最大限度减少在Windows Presentation Foundation(WPF)中创建自定义控件以及其他控件创作模型的需要的功能。
本主题还演示如何创建新控件。
编写新控件的替代方法以前,如果要通过现有控件获取自定义体验,您只能更改控件的标准属性,例如背景色、边框宽度和字号。
如果希望在这些预定义参数的基础之上扩展控件的外观或行为,则需要创建新的控件,通常的方法是继承现有控件并重写负责绘制该控件的方法。
虽然这仍是一种可选方法,但也可以利用WPF丰富内容模型、样式、模板和触发器来自定义现有的控件。
下面的列表提供了一些示例,演示如何在不创建新控件的情况下使用这些功能来实现统一的自定义体验。
丰富内容。
很多标准WPF控件支持丰富内容。
例如,Button的内容属性为Object类型,因此从理论上讲,任何内容都可以显示在Button上。
若要让按钮显示图像和文本,可以将图像和TextBlock添加到StackPanel中,然后将StackPanel分配给Content属性。
由于这些控件可以显示WPF可视化元素和任意数据,因此,减少了创建新控件或修改现有控件来支持复杂可视化效果的需要。
样式。
Style是表示控件属性的值的集合。
使用样式可创建所需控件外观和行为的可重用表示形式,而无需编写新控件。
wpf自定义控件(包含依赖属性以及事件)
wpf⾃定义控件(包含依赖属性以及事件)创建了这个依赖属性,就可以直接在对应的控件中使⽤了,就像是button中⼀开始就内置的width等属性⼀样,这个在设计⾃定义控件的时候⽤的尤其多下⾯讲的是⾃定义分页控件代码:<UserControl x:Class="WPFDataGridPaging.Pager"xmlns="/winfx/2006/xaml/presentation"xmlns:x="/winfx/2006/xaml"xmlns:mc="/markup-compatibility/2006"xmlns:d="/expression/blend/2008"xmlns:local="clr-namespace:WPFDataGridPaging"mc:Ignorable="d"d:DesignHeight="30" d:DesignWidth="220"><UserControl.Resources><Style TargetType="{x:Type Button}"><Setter Property="Width" Value="22"/><Setter Property="Height" Value="22"/></Style></UserControl.Resources><Grid><StackPanel Orientation="Horizontal"><Button x:Name="FirstPageButton" Margin="5,0" Click="FirstPageButton_Click"><Path Width="7" Height="10" Data="M0,0L0,10 M0,5L6,2 6,8 0,5" Stroke="Black" StrokeThickness="1"Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"/></Button><Button x:Name="PreviousPageButton" Margin="0,0,5,0" Click="PreviousPageButton_Click"><Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"/></Button><TextBlock VerticalAlignment="Center"><Run Text="第"/><Run x:Name="rCurrent" Text="0"/><Run Text="页"/></TextBlock><Button Margin="5,0" x:Name="NextPageButton" Click="NextPageButton_Click"><Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"><Path.RenderTransform><RotateTransform Angle="180" CenterX="4" CenterY="4"/></Path.RenderTransform></Path></Button><Button Margin="0,0,5,0" x:Name="LastPageButton" Click="LastPageButton_Click"><Path x:Name="MainPath" Width="7" Height="10" Data="M0,0L0,10 M0,5 L6,2 6,8 0,5"Stroke="Black" StrokeThickness="1" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"><Path.RenderTransform><RotateTransform Angle="180" CenterX="3" CenterY="5"/></Path.RenderTransform></Path></Button><TextBlock VerticalAlignment="Center"><Run Text="共"/><Run x:Name="rTotal" Text="0"/><Run Text="页"/></TextBlock></StackPanel></Grid></UserControl>界⾯:后台代码:public partial class Pager : UserControl{#region声明事件和依赖属性public static RoutedEvent FirstPageEvent;public static RoutedEvent PreviousPageEvent;public static RoutedEvent NextPageEvent;public static RoutedEvent LastPageEvent;public static readonly DependencyProperty CurrentPageProperty;public static readonly DependencyProperty TotalPageProperty;#endregionpublic string CurrentPage{get { return (string)GetValue(CurrentPageProperty); }set { SetValue(CurrentPageProperty, value); }}public string TotalPage{get { return (string)GetValue(TotalPageProperty); }set { SetValue(TotalPageProperty, value); }}public Pager(){InitializeComponent();}static Pager(){#region注册事件以及依赖属性//注册FirstPageEvent事件,事件的拥有者是Pager,路由事件的名称是FirstPage,这是唯⼀的FirstPageEvent = EventManager.RegisterRoutedEvent("FirstPage", RoutingStrategy.Direct,typeof(RoutedEventHandler), typeof(Pager));PreviousPageEvent = EventManager.RegisterRoutedEvent("PreviousPage", RoutingStrategy.Direct,typeof(RoutedEventHandler), typeof(Pager));NextPageEvent = EventManager.RegisterRoutedEvent("NextPage", RoutingStrategy.Direct,typeof(RoutedEventHandler), typeof(Pager));LastPageEvent = EventManager.RegisterRoutedEvent("LastPage", RoutingStrategy.Direct,typeof(RoutedEventHandler), typeof(Pager));//注册⾃定义的依赖属性CurrentPageProperty = DependencyProperty.Register("CurrentPage",typeof(string), typeof(Pager), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnCurrentPageChanged))); TotalPageProperty = DependencyProperty.Register("TotalPage",typeof(string), typeof(Pager), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnTotalPageChanged)));#endregion}public event RoutedEventHandler FirstPage{add { AddHandler(FirstPageEvent, value); }remove { RemoveHandler(FirstPageEvent, value); }}public event RoutedEventHandler PreviousPage{add { AddHandler(PreviousPageEvent, value); }remove { RemoveHandler(PreviousPageEvent, value); }}public event RoutedEventHandler NextPage{add { AddHandler(NextPageEvent, value); }remove { RemoveHandler(NextPageEvent, value); }}public event RoutedEventHandler LastPage{add { AddHandler(LastPageEvent, value); }remove { RemoveHandler(LastPageEvent, value); }}///<summary>///依赖属性回调⽅法///</summary>///<param name="d"></param>///<param name="e"></param>public static void OnTotalPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){Pager p = d as Pager;if (p != null){Run rTotal = (Run)p.FindName("rTotal");rTotal.Text = (string)e.NewValue;}}private static void OnCurrentPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){Pager p = d as Pager;if (p != null){Run rCurrrent = (Run)p.FindName("rCurrent");rCurrrent.Text = (string)e.NewValue;}}private void FirstPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(FirstPageEvent, this));}private void PreviousPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(PreviousPageEvent, this));}private void NextPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(NextPageEvent, this));}private void LastPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(LastPageEvent, this));}}上⾯就是⾃定义的⼀个分页控件,如果我们想要使⽤这个控件,如下:<Window x:Class="WPFDataGridPaging.MainWindow"xmlns="/winfx/2006/xaml/presentation"xmlns:x="/winfx/2006/xaml"xmlns:d="/expression/blend/2008"xmlns:mc="/markup-compatibility/2006"xmlns:i="/expression/2010/interactivity"xmlns:local="clr-namespace:WPFDataGridPaging"mc:Ignorable="d"Title="MainWindow" Height="350" Width="525"><Grid><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><DataGrid Grid.Row="0" ItemsSource="{Binding FakeSource}" AutoGenerateColumns="False" CanUserAddRows="False"> <DataGrid.Columns><DataGridTextColumn Header="Item Id" Binding="{Binding Id}" Width="80"/><DataGridTextColumn Header="Item Name" Binding="{Binding ItemName}" Width="180"/></DataGrid.Columns></DataGrid><!-- TotalPage 和CurrentPage就是在Pager中⾃定义的依赖属性,可以在这⾥直接来⽤--><local:Pager TotalPage="{Binding TotalPage}"CurrentPage="{Binding CurrentPage, Mode=TwoWay}"HorizontalAlignment="Center"Grid.Row="1"><i:Interaction.Triggers><!--EventName="FirstPage" 这⾥FirstPage就是前⾯注册事件的时候默认的事件名称,必须要唯⼀ --><i:EventTrigger EventName="FirstPage"><i:InvokeCommandAction Command="{Binding FirstPageCommand}"/></i:EventTrigger><i:EventTrigger EventName="PreviousPage"><i:InvokeCommandAction Command="{Binding PreviousPageCommand}"/></i:EventTrigger><i:EventTrigger EventName="NextPage"><i:InvokeCommandAction Command="{Binding NextPageCommand}"/></i:EventTrigger><i:EventTrigger EventName="LastPage"><i:InvokeCommandAction Command="{Binding LastPageCommand}"/></i:EventTrigger></i:Interaction.Triggers></local:Pager></Grid></Window>界⾯:后台代码:///<summary>/// Interaction logic for MainWindow.xaml///</summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();//这⾥⼀定要注意,⼀定要将模型加到上下⽂中,要不然依赖属性和事件都不会触发,在实际开发中是不可能⼀打开 //界⾯就开始加载出来数据的,所以可以通过ObservableCollection形式绑定表格数据,//⽽需要绑定事件和依赖属性的需要将其绑定到上下⽂中DataContext = new MainViewModel();}}MainViewModel:public class MainViewModel : ViewModel{private ICommand _firstPageCommand;public ICommand FirstPageCommand{get{return _firstPageCommand;}set{_firstPageCommand = value;}}private ICommand _previousPageCommand;public ICommand PreviousPageCommand{get{return _previousPageCommand;}set{_previousPageCommand = value;}}private ICommand _nextPageCommand;public ICommand NextPageCommand{get{return _nextPageCommand;}set{_nextPageCommand = value;}}private ICommand _lastPageCommand;public ICommand LastPageCommand{get{return _lastPageCommand;}set{_lastPageCommand = value;}}private int _pageSize;public int PageSize{get{return _pageSize;}set{if(_pageSize != value){_pageSize = value;OnPropertyChanged("PageSize"); }}}private int _currentPage;public int CurrentPage{get{return _currentPage;}set{if(_currentPage != value){_currentPage = value;OnPropertyChanged("CurrentPage"); }}}private int _totalPage;public int TotalPage{get{return _totalPage;}set{if(_totalPage != value){_totalPage = value;OnPropertyChanged("TotalPage"); }}}///<summary>/// ObservableCollection表⽰⼀个动态数据集合,它可在添加、删除项⽬或刷新整个列表时提供通知。
VBA中的用户界面设计和自定义控件
VBA中的用户界面设计和自定义控件随着计算机技术的不断发展,用户界面设计在软件开发中扮演着越来越重要的角色。
VBA(Visual Basic for Applications)作为一种强大的编程语言,提供了丰富的工具和功能,使得用户界面设计和自定义控件变得更加灵活和易于实现。
本文旨在介绍VBA中的用户界面设计和自定义控件的相关内容。
在VBA中,用户界面设计往往基于表单(Form)。
通过表单,可以创建交互性强、用户友好的应用程序。
VBA提供了丰富的控件类型,如文本框、标签、按钮、列表框等,可以用来构建界面元素。
用户可以通过拖拽的方式将这些控件添加到表单上,并进行相应的属性设置和事件编写,实现丰富的用户界面交互效果。
在进行用户界面设计时,设计原则和技巧是非常重要的。
首先,界面整洁简明,避免过多的控件和复杂的布局,以免用户感到困扰。
其次,界面要符合用户的直观操作习惯,提供清晰明了的导航和操作指引。
此外,界面的美观性和色彩搭配也是需要考虑的因素,可以根据应用程序的定位和目标用户来选择适合的主题和风格。
除了基本的表单控件外,VBA还支持自定义控件的创建和使用。
自定义控件可以满足特定业务需求,并且可以根据个人偏好进行灵活的定制。
VBA中的自定义控件可以通过编程方式创建,也可以通过ActiveX控件或Windows API实现。
编程方式创建自定义控件需要使用VBA提供的控件对象模型。
通过创建类模块和控件模块,可以定义新的控件类型,并在需要的地方使用。
自定义控件具有更高的灵活性和扩展性,可以根据实际需求设置不同的属性和事件,实现个性化的用户界面。
通过ActiveX控件,开发者可以使用第三方控件库,如Microsoft Office裡的常用控件,以扩展VBA的功能。
ActiveX控件是可重用的二进制组件,可以在VBA开发环境中进行使用。
这些控件具有更丰富的功能和更好的性能,可以提升用户界面的体验和效果。
另外,使用Windows API可以调用操作系统提供的功能和控件,实现更高级的用户界面效果。
在WPF中自定义控件
承,打造 CustomControl 时其会为从 System.Windows.Controls.Control 继承.但实际情况下,也许我们从他们的衍生类别开始继承会得到更多的好处(更好的重 用已 有的逻辑),比如你的控件拥有更多的类似于 Button 的某些特性,那么从 Button 开始继承就比从 Control 继承少写很多代码.
二,UserControl 还是 CustomControl? 要在 WPF 中自定义一个控件,使用 UserControl 与 CustomControl 都是 不错的选择(除此之外,还有更多选择,比如打造一个自定义的面板,但这不在本文
的讨论范围),他们的区别在于: UserControl,其更像 WinForm 中自定义控件的开发风格,在开发上更简单快速,几乎可以简单地理解为:利用设计器来将多个已有控件作为子元素来拼凑
在 VS 中右键单击你的项目,点击"添加新项目",在出现的选择列表中选择"UserControl",VS 会自动为你生成一个*.xaml 文件以及其对应 的后台代码文件
2
(*.cs 或其它). 值得注意的是,自动生成的代码中,你的控件是继承于 erControl 类的,这对应你的控件而 言并不一定是最恰当的基 类,你可以修改它,但注意你应该同时修改*.cs 文件和*.xaml 文件中的基类,而不只是修改*.cs 文件,否则当生成项目时会 报错"不是继承于同一基类".修改 *.xaml 文件的方法是:将该文件的第一行和最后一行的"UserControl" 改成与你认为恰当的基类名称.
WPF---控件模板(一)
WPF---控件模板(⼀)⼀、控件模板概述控件的外观通过⼀个ControlTemplate类型的对象确定,该对象指定了组成⼀个控件的显⽰的各种视觉元素。
当WPF创建⼀个控件时,会创建⼀个控件类(模板⽗)的实例,然后实例化通过它的ControlTemplate设定的这个控件的外观树(组成这个控件的内部UI元素)。
⼆、开发⾃定义的简单控件模板为了简单起见,我们开发⼀个简单的Button控件模板。
步骤参见以下:1)在Window的Resources中定义⼀个名字为myButtonTemplate的控件模板2)在使⽤StaticResource标记扩展为Button的Template属性赋值⾄此,⼀个简单的Button的ControlTemplate就算开发好了,但是仔细看图,我们会发现⼀个问题,我们按钮实际显⽰的⽂本信息与我们设定的⽂本信息是不⼀致的,这不是我们的预期,就连背景⾊和Border的颜⾊也不是我们的预设值,⽽是使⽤了模板的默认值,那么我们该如何修改控件模板来达到我们的预期呢?三、控件模板之TemplateBinding为了达到上述预期的效果,我们可以使⽤TemplateBinding将控件模板中的属性绑定到控件本⾝(模板⽗)。
参见以下代码:从图中可以看出,现在已经达到了预期的效果。
为了达到上述同样显⽰⽂本的效果,我们也可以使⽤ContentPresenter。
四、ContentPresenter对象1)ContentPresenter作为⼀个占位符,⽤来在模板中指定Content应该放置的位置;2)默认情况下,ContentPresenter从模板⽗(应⽤控件模板的控件本⾝)获取实际的内容,然后绑定到⾃⼰的Content属性;3)为了使⽤ContentPresenter,我们需要设置ControlTemplate的TargetType属性为模板⽗的类型。
使⽤了ContentPresenter的ControlTemplate参见以下:五、触发器1)Trigger必须在ControlTemplate.Triggers的节点下;2)Triggers集合中可以包含任意数量的Trigger;3)⼀个Trigger可以有任意数量的Setter;4)每个Setter中指定三个属性,分别是TargetName、Property和Value。
[WPF自定义控件]简单的表单布局控件
[WPF ⾃定义控件]简单的表单布局控件1. WPF布局⼀个表单在WPF 中布局表单⼀直都很传统,例如使⽤上⾯的XAML ,它通过Grid 布局⼀个表单。
这样出来的结果整整齐齐,看上去没什么问题,但当系统⾥有⼏⼗个表单页以后需要统⼀将标签改为上对齐,或者标签和控件中加⼀个:号等需求都会难倒开发⼈员。
⼀个好的做法是使⽤某些控件库提供的表单控件;如果不想引⼊⼀个这么“重”的东西,可以⾃⼰定义⼀个简单的表单控件。
这篇⽂章介绍⼀个简单的⽤于布局表单的Form 控件,虽然是⼀个很⽼的⽅案,但我很喜欢这个控件,不仅因为它简单实⽤,⽽且是⼀个很好的结合了ItemsControl 、ContentControl 、附加属性的教学例⼦。
Form 是⼀个⾃定义的ItemsControl ,部分代码可以参考这篇⽂章。
2. ⼀个古⽼的⽅法即使抛开验证信息、确认取消这些更⾼级的需求(表单的其它功能真的很多很多,但这篇⽂章只谈论布局),表单布局仍是个⼗分复杂的⼯作。
幸好⼗年前ScottGu 分享过⼀个,很有参考价值:Karl Shifflett has another great WPF blog post that covers a cool way to perform flexible form layout for LOB scenarios.<Grid Width="400" HorizontalAlignment="Center" VerticalAlignment="Center"><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition Height="Auto" /><RowDefinition Height="Auto" /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition Width="*" /></Grid.ColumnDefinitions><TextBlock Text="⽤户名" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="4" /><TextBox Grid.Column="1" Margin="4" /><TextBlock Text="密码" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="4" Grid.Row="1" /><PasswordBox Grid.Row="1" Grid.Column="1" Margin="4" /><TextBlock Grid.Row="2" Text="确认密码" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="4" /><PasswordBox Grid.Column="1" Grid.Row="2" Margin="4" /></Grid>使⽤代码和截图如上所⽰。
WPF自定义控件第一
WPF⾃定义控件第⼀本⽂主要针对WPF新⼿,⾼⼿可以直接忽略,更希望⾼⼿们能给出⼀些更好的实现思路。
前期⼀个⼩任务需要实现⼀个类似含步骤进度条的控件。
虽然对于XAML的了解还不是⾜够深⼊,还是摸索着做了⼀个。
这篇⽂章介绍下实现这个控件的步骤,最后会放出代码。
还请⾼⼿们给出更好的思路。
同时也希望这⾥的思路能给同道中⼈⼀些帮助。
话不多说,开始正题。
实现中的⼀些代码采⽤了⽹上现有的⽅案,代码中通过注释标记了来源,再次对代码作者⼀并表⽰感谢。
⾸先放⼀张最终效果图。
节点可以被点击控件会根据绑定的集合数据⽣成⼀系列节点,根据集合中的数据还可以按⽐例放置节点的位置。
节点的实体代码如下:1234 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19public class FlowItem{public FlowItem(){}public FlowItem(int id, string title,double offsetRate) {Id = id;Title = title;OffsetRate = offsetRate;}public int Id { get; set; }public string Title { get; set; }public double OffsetRate { get; set; }}其中三个属性分别代表了节点的编号,标题和偏移量(⽤来确定节点在整个条中的位置)。
控件的实现忘了很久以前在哪看到过⼀句话,说设计WPF控件时不⼀定按照MVVM模式来设计,但⼀定要确保设计的控件可以按照MVVM模式来使⽤。
本控件也是本着这么⽬标来完成。
控件实现为TemplatedControl,个⼈认为这种⽅式更为灵活,做出来的控件可复⽤度更⾼。
反之UserControl那种组合控件的⽅式更适⽤于⼀个项⽬内复⽤的需要。
遵循⼀般的原则,我们将控件单独放于⼀个项⽬中。
在TemplatedControl项⽬中,“模板”即XAML内容⼀般都放置在⼀个名为Generic.xaml⽂件中,这个⽂件应该放置在解决⽅案Themes⽂件夹下。
WPF自定义控件创建
WPF⾃定义控件创建本⽂简单的介绍⼀下WPF⾃定义控件的开发。
⾸先,我们打开VisualStudio创建⼀个WPF⾃定义控件库,如下图:然后,我们可以看到创建的解决⽅案如下:在解决⽅案中,我们看到了⼀个Themes⽂件夹和⼀个CS⽂件。
其中CS⽂件,就是我们需要编写的⾃定义控件,⾥⾯的类继承了Control类;⽽Themes则存放该控件的样式。
即,WPF⾃定义控件,是通过样式给我们的编辑的控件类披上外⾐⽽形成的。
下⾯,我们来编写⼀个简单的时间控件。
我们先将CustomControl1⽂件改名为KibaDateTime,然后打开KibaDateTime.cs⽂件,看到了⼀些控件应⽤提⽰,这些提⽰写的是⾃定义控件的应⽤⽅式,我们先不看这些提⽰,因为他写的不是很好理解。
接下来我们开始编写时间控件,修改KibaDateTime类如下:public class KibaDateTime : TextBox{private static Regex regex = new Regex("[0-9]+");#region ⼩时public static readonly DependencyProperty HourProperty = DependencyProperty.Register("Hour", typeof(int), typeof(KibaDateTime), new FrameworkPropertyMetadata(00));public int Hour{get{return (int)GetValue(HourProperty);}set{SetValue(HourProperty, value);}}#endregion#region 分钟public static readonly DependencyProperty MinuteProperty = DependencyProperty.Register("Minute", typeof(int), typeof(KibaDateTime), new FrameworkPropertyMetadata(00));public int Minute{get{return (int)GetValue(MinuteProperty);}set{SetValue(MinuteProperty, value);}}#endregion#region 秒public static readonly DependencyProperty SecondProperty = DependencyProperty.Register("Second", typeof(int), typeof(KibaDateTime), new FrameworkPropertyMetadata(00));public int Second{get{return (int)GetValue(SecondProperty);}set{SetValue(SecondProperty, value);}}#endregionstatic KibaDateTime(){//当此依赖项属性位于指定类型的实例上时为其指定替换元数据,以在该依赖项属性继承⾃基类型时重写该属性已存在的元数据。
WPF创建自定义控件并运用
WPF创建⾃定义控件并运⽤此项⽬源码:⾸先创建⾃定义控件库项⽬项⽬名称命名为:WpfCustomControlLibrary在CustomControl1.cs⽂件中添加新控件类BulletCheckBox///<summary>/// BulletCheckBox.xaml 的交互逻辑///</summary>public class BulletCheckBox : CheckBox{public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(BulletCheckBox), new PropertyMetadata("Off"));///<summary>///默认⽂本(未选中)///</summary>public string Text{get { return (string)GetValue(TextProperty); }set { SetValue(TextProperty, value); }}public static readonly DependencyProperty CheckedTextProperty = DependencyProperty.Register("CheckedText", typeof(string), typeof(BulletCheckBox), new PropertyMetadata("On"));///<summary>///选中状态⽂本///</summary>public string CheckedText{get { return (string)GetValue(CheckedTextProperty); }set { SetValue(CheckedTextProperty, value); }}public static readonly DependencyProperty CheckedForegroundProperty =DependencyProperty.Register("CheckedForeground", typeof(Brush), typeof(BulletCheckBox), new PropertyMetadata(Brushes.WhiteSmoke));///<summary>///选中状态前景样式///</summary>public Brush CheckedForeground{get { return (Brush)GetValue(CheckedForegroundProperty); }set { SetValue(CheckedForegroundProperty, value); }}public static readonly DependencyProperty CheckedBackgroundProperty =DependencyProperty.Register("CheckedBackground", typeof(Brush), typeof(BulletCheckBox), new PropertyMetadata(Brushes.LimeGreen));///<summary>///选中状态背景⾊///</summary>public Brush CheckedBackground{get { return (Brush)GetValue(CheckedBackgroundProperty); }set { SetValue(CheckedBackgroundProperty, value); }}static BulletCheckBox(){DefaultStyleKeyProperty.OverrideMetadata(typeof(BulletCheckBox), new FrameworkPropertyMetadata(typeof(BulletCheckBox)));}}为BulletCheckBox这个控件增加样式<Style TargetType="{x:Type local:BulletCheckBox}"><Setter Property="Background" Value="#FF4A9E4A"></Setter><Setter Property="Foreground" Value="#DDE8E1"></Setter><Setter Property="CheckedForeground" Value="White"></Setter><Setter Property="CheckedBackground" Value="#FF0CC50C"></Setter><Setter Property="FontSize" Value="13"></Setter><Setter Property="Cursor" Value="Hand"></Setter><Setter Property="Width" Value="750"></Setter><Setter Property="Height" Value="280"></Setter><Setter Property="Margin" Value="1"></Setter><Setter Property="Template"><Setter.Value><!--控件模板--><ControlTemplate TargetType="{x:Type local:BulletCheckBox}"><Viewbox Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center"><Border x:Name="border" Width="75" Height="28" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"Margin="{TemplateBinding Margin}" CornerRadius="14"><StackPanel Orientation="Horizontal"><!--状态球--><Border x:Name="state" Width="24" Height="24" Margin="3,2,1,2" CornerRadius="12" SnapsToDevicePixels="True"Background="{TemplateBinding Foreground}"><Border.RenderTransform><TranslateTransform x:Name="transState" X="0"></TranslateTransform></Border.RenderTransform></Border><!--⽂本框--><TextBlock Width="40" Foreground="{TemplateBinding Foreground}" x:Name="txt" Text="{TemplateBinding Text}" VerticalAlignment="Center" TextAlignment="Center"> <TextBlock.RenderTransform><TranslateTransform x:Name="transTxt" X="0"></TranslateTransform></TextBlock.RenderTransform></TextBlock></StackPanel></Border></Viewbox><!--触发器:设置选中状态符号--><ControlTemplate.Triggers><Trigger Property="IsChecked" Value="True"><Setter Property="Text" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedText}" TargetName="txt"/><Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedForeground}" TargetName="state"/><Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedForeground}" TargetName="txt"/><Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedBackground}" TargetName="border"/><Trigger.EnterActions><BeginStoryboard><Storyboard><DoubleAnimation Storyboard.TargetName="transState" Storyboard.TargetProperty="X" To="45" Duration="0:0:0.2" /><DoubleAnimation Storyboard.TargetName="transTxt" Storyboard.TargetProperty="X" To="-24" Duration="0:0:0.2" /></Storyboard></BeginStoryboard></Trigger.EnterActions><Trigger.ExitActions><BeginStoryboard><Storyboard><DoubleAnimation Storyboard.TargetName="transState" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" /><DoubleAnimation Storyboard.TargetName="transTxt" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" /></Storyboard></BeginStoryboard></Trigger.ExitActions></Trigger><Trigger Property="IsEnabled" Value="false"><Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="border"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>编译项⽬得到DLL控件库⽂件⾃定义控件库⽣成完后,就可以创建WPF应⽤程序来调⽤它了,右击解决⽅案->添加->新建项⽬->WPF应⽤右击WpfApp1项⽬设为启动项⽬,右击该项⽬下的引⽤,添加引⽤从浏览中找到我们刚才⽣成的DLL控件库⽂件此时展开引⽤就可以看到刚才⽣成的控件库已经加载进来了打开MainWindow.xaml,添加引⽤xmlns:MyNamespace="clr-namespace:WpfCustomControlLibrary;assembly=WpfCustomControlLibrary"这句引⽤是在CustomControl1.cs⽂件中复制⽽来的,其中xmlns:MyNamespace是可以更改的后台⽂件不⽤改动,整个MainWindow.xaml⽂件如下:<Window x:Class="WpfApp1.MainWindow"xmlns="/winfx/2006/xaml/presentation"xmlns:x="/winfx/2006/xaml"xmlns:d="/expression/blend/2008"xmlns:mc="/markup-compatibility/2006"xmlns:MyNamespace="clr-namespace:WpfCustomControlLibrary;assembly=WpfCustomControlLibrary"xmlns:local="clr-namespace:WpfApp1"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><MyNamespace:BulletCheckBox Text="关闭" CheckedText="开启" IsChecked="True" Width="100" Height="100" /></Grid></Window>最后运⾏程序:。
WPF设计自定义控件
在实际工作中,WPF提供的控件并不能完全满足不同的设计需求。
这时,需要我们设计自定义控件。
这里LZ总结一些自己的思路,特性如下:∙Coupling∙UITemplate∙Behaviour∙Function Package下面举例说说在项目中我们经常用到调音台音量条,写一个自定义控件模拟调音台音量条。
自定义控件SingnalLight,实现功能∙接收来自外部的范围0~100的数值∙实时显示接收数值∙数值范围0~50显示绿色,50~85显示黄色,85~100显示红色,没有数值显示褐色∙可在父控件上拖拽该控件首先New WPF Application Project,在Ui上放2个Button,代码:1 <Grid>2 <StackPanelOrientation="Horizontal" VerticalAlignment="Bottom">3<Button Content="Start" Click="Start_Click"></Button>4<Button Content="Stop" Click="Stop_Click"></Button>5</StackPanel>6 </Grid>Start,Stop事件实现1private void Start_Click(object sender, RoutedEventArgs e) {2SignalManager.Instance.Start();3 }45private void Stop_Click(object sender, RoutedEventArgs e) {6SignalManager.Instance.Stop();7 }这里创建一个SignalManager类,在Start时开启一个计时器,每隔1秒生成一个0~100的随机数,并作为模拟数值输出。
wpf 创建用户控件实例的方法
wpf 创建用户控件实例的方法WPF(Windows Presentation Foundation)是一种用于创建Windows 桌面应用程序的技术,它提供了丰富的UI 组件库和样式功能。
在WPF 应用程序中,用户控件(User Control)是一种重要的组成部分,它允许开发者自定义UI 界面。
本文将介绍如何在WPF 中创建用户控件实例,并在应用程序中使用它们。
1.WPF 用户控件概述WPF 用户控件是一种可重用的UI 组件,它可以包含在任何WPF 窗口或页面中。
用户控件可以自定义样式、布局和功能,以满足特定需求。
WPF 提供了两种主要方法来创建用户控件:继承自BaseControl 类和继承自UserControl 类。
2.创建WPF 用户控件的方法2.1 继承自BaseControl 类要使用这种方法,需要创建一个新类,该类继承自BaseControl 类,然后在该类中添加所需的UI 元素和事件处理程序。
以下是一个简单的例子:```csharppublic class MyUserControl : BaseControl{public MyUserControl(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){MessageBox.Show("按钮被点击了!");}}```2.2 继承自UserControl 类继承自UserControl 类是一种更灵活的方法,因为它允许您使用XAML 标记来定义UI 元素。
以下是一个示例:```csharppublic class MyUserControl : UserControl{public MyUserControl(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){MessageBox.Show("按钮被点击了!");}}```2.3 使用MarkupExtension 创建自定义控件MarkupExtension 是一种WPF 标记扩展,可用于创建自定义控件。
VB编程常用控件(一)
第二章常用控件(一)在第一章中,我们已对用VB编写应用程序作一大致的了解:先分析问题,再设计用户界面,最后才去编写必要的事件过程。
好,现在让我们一起先来学习窗体、几个常用的控件及简单的界面设计规则。
2.1 窗体窗体是一种具有自身特定属性、方法和事件的对象,VB程序的基本构造模块,是运行应用程序时用户交互操作的实际窗口,也是其他对象的载体,它具有Windows窗体的基本特性,包括标题栏、控制菜单、窗体边框和窗口区。
图2.1应用程序窗体的外观打开VB一、窗体的属性1.属性的设置方法一:属性窗口方法二:在程序中用程序代码设置:窗体名称.属性名=属性值。
如:Form1.caption=“计算器”2.常用属性Caption、Height、Left、Name、T op、Visible、Width、AutoRedraw、backcolor、CurrentX、CurrentY、Enabled、FillColor、FontStyle、FontBold、FontItalic、FontName、FontSize、FontStrikethru、FontUnderline、ForeColor、MaxButton、MinButton、Picture、ScaleHeight、ScaleLeft、ScaleMode、ScaleWidth、ScaleTop、WindowState等(1)名称标识:Name属性:用来标识窗体的名称,是字符串类型,它是一个以字母开头由字母、数字和下划线组成的长度不超过40个字符的字符串,最好设置一个有实际意义的名称,如:frmCalculator。
该属性值不允许与其他对象重名,也不允许使用Visual Basic的保留关键字和对象名,系统默认为在Form后加上1,2等。
(2) 外观:Caption(标题)属性:用于设置窗体标题内容,其值是一个字符串。
BorderStyle(边界)属性:用于控制窗体边界的类型,表现窗体的显示风格,它有六个可选值(见表2.1)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
简单易学图文并茂创作控件自己创作控件,分三种主要的形式:复合控件,扩展控件,和自定义控件。
复合控件,顾名思义就是把现有的进行组合,让它们协作形成功能强大的新控件;扩展控件,是以某一现有控件为基础,让它具有新的功能;自定义控件,则是由作者完全操刀,建立一个全新的控件。
可以用一个比喻来理解这三种形式的区别:复合控件,就是你买好各个电脑配件,组装成一台电脑;扩展控件,就是把显卡上的零件更换几个,让它能力比标准产品更强大;自定义控件,就是自己制作一个名为“生人勿近”的硬件,他可以通过PCI插槽,安装到电脑上,一旦生人走近,它能识别并发出狗叫……综上,三种形式中,复合控件相对来说是最简单的;扩展控件在其次;自定义控件最难。
通常,我们使用前两种技术,就能创作出很复杂的控件了。
范例1:Excel的单元格Cell,当它没有焦点的时候,就是一个TextBlock,当它获得焦点,可以编辑的时候,就是一个TextBox框。
这样一个控件,将是我们今后制作表格控件的基础。
范例1中,我们会用到两种技术,复合控件和扩展控件。
在VS中,要进行如下的工作(推荐使用VS2010)1.新建一个Solution,名为Cell;2.添加一个名为“TestAPP”的WFP项目。
我们用他来测试成果;3.添加一个名为“Ctrl_Cell”的WFP用户控件项目。
然后,我们需要一个TextBlock,和一个TextBox控件,这是我们的演员。
考虑一下它们应该怎样演出,才能达到我们需要的效果:●平时这个控件,应该表现出TextBlock的外观;●当我们点击这个Label时,隐藏的TextBox控件跑到TextBlock的前面,并且它显示的值和TextBlock一样。
同时,这个值是可以编辑的;●编辑完TextBox的内容,按下Enter,或者点击屏幕上的其他控件,让TextBox失去焦点,TextBox消失。
TextBlock跑到前面来,并且显示编辑后的内容。
接着,需要考虑一下这个控件的属性和事件。
1.它应该有一个Value属性,Label显示这个Value;同时Text也显示这个Value;我们编辑的时候,也是针对这个Value。
2.点击TextBlock时,会发生一系列的变化。
所以我们要关注TextBlock的MouseDown事件。
3.编辑TextBox,按下Enter后,或者TextBox失去焦点,会发生一系列的变化。
所以我们要关注TextBox接受了Enter键这个输入,同时也要关注它的LostFocus事件。
关于“TextBox控件接受到一个Enter输入”的问题。
基础的TextBox控件是没有这个功能的,而我们今后要用到的地方很多。
所以我考虑扩展一下TextBox的功能,制作一个Ex_TextBox。
新的控件在用户按下Enter的时候,产生一个getEnterKey的事件,这样使用者就能处理这条消息了。
扩展现有控件,直接在原有的TextBox上继承,把一个判断键盘输入值的程序afterGetEnter绑定到Keydown事件下。
在Ctrol_Cell项目下,添加一个新的类,名为Ex_TextBox。
*******************代码********************Public Class Ex_TextBoxInherits TextBox'这个控件扩展了现有TextBox的功能。
'当用户输入Enter的时候,引发一个getEnterKey事件。
'这样,控件的使用者,就能在输入Enter的时候,得到一个信息。
'扩展控件功能,属于创作控件的第二种技术。
Public Event getEnterKey As EventHandlerPrivate Sub afterGetEnter(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyDownIf e.Key = Key.Enter ThenRaiseEvent getEnterKey(sender, e)End IfEnd SubEnd Class*******************代码********************如此,用户按下Enter后,Ex_TextBox就发出一个getEnterKey事件。
使用者今后编写响应这个事件的代码就可以了。
最后,我们在Cell的UI上,添加一个TextBlock和一个Ex_TextBox。
其UI代码如下:*******************代码********************<UserControl x:Class="Ctrl_Cell"xmlns="/winfx/2006/xaml/presentation"xmlns:x="/winfx/2006/xaml"xmlns:mc="/markup-compatibility/2006"xmlns:d="/expression/blend/2008"mc:Ignorable="d"d:DesignHeight="300" d:DesignWidth="182" Height="23" xmlns:my="clr-namespace:Ctrl_Label_Text"><Grid><TextBlock Height="23" HorizontalAlignment="Stretch" Margin="0" Name="TextBlock1" Text="TextBlock" VerticalAlignment="Top" Background="#FF8DD66D" Padding="1" /><my:Ex_TextBox Height="23" HorizontalAlignment="Stretch" Margin="0" x:Name="Ex_TextBox1" VerticalAlignment="Stretch" Width="Auto" Visibility="Hidden" VerticalScrollBarVisibility="Hidden" Background="#FF8DD66D" BorderThickness="0" /> </Grid></UserControl>*******************代码********************控件的外观如下:要添加Value属性,并描述控件的行为,还需要添加一些代码:*******************代码********************Public Class Ctrl_CellPrivate p_value As String '这是Cell的Value属性Public Property Value As StringGetReturn Me.p_valueEnd GetSet(ByVal value As String)Me.p_value = valueMe.TextBlock1.Text = valueEnd SetEnd PropertyPrivate Sub ShowExTextBox(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBlock1.MouseDown'把显示Ex_TextBox的动作,和点击TextBlock事件绑定起来Me.Ex_TextBox1.Visibility = Windows.Visibility.VisibleMe.TextBlock1.Visibility = Windows.Visibility.HiddenMe.Ex_TextBox1.Focus()End SubPrivate Sub MyInit()'把显示TextBlock的动作,和Ex_Textbox得到Enter,以及失去焦点这两个事件绑定起来AddHandler Ex_TextBox1.getEnterKey, AddressOf Me.ShowTextBlockAddHandler Ex_TextBox1.LostFocus, AddressOf Me.ShowTextBlockEnd SubPrivate Sub ShowTextBlock(ByVal sender As Object, ByVal e As System.EventArgs) '这是从Ex_TextBox切换到TextBlock的动作Me.TextBlock1.Visibility = Windows.Visibility.VisibleMe.Value = Me.Ex_TextBox1.TextMe.Ex_TextBox1.Visibility = Windows.Visibility.HiddenEnd SubPublic Sub New()' 此调用是设计器所必需的。
InitializeComponent()' 在InitializeComponent() 调用之后添加任何初始化。
Me.MyInit() '调用自己的初始化代码End SubEnd Class*******************代码********************这样,Cell的设计就完成了。
在TestAPP中测试一下:在UI上放一个Cell控件。
并添加一个按钮:按钮查看Cell的Value,代码如下:*******************代码********************Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.ClickMsgBox(Me.Cell1.Value)End Sub*******************代码********************当Cell没有点击的时候,它是一个TextBlock;点击它,变成一个TextBox,可以接受用户的输入;修改内容并按下Enter后,切换回TextBlock,内容也修改了;修改内容,直接点击旁边的按钮,也能切换回TextBlock;按钮显示的是Cell的值。