抱歉,格式还是不够顺眼,从word复制过来,格式有了一些变化,虽然用Live Writer重排,但实在是麻烦。改天,我放Word附件上来。^_^

另外,请各位指点,教程怎样写,读者会更有兴趣。

01. 创建软件雏形

这个雏形包括4个项目(Project):

  1. 一个主程序(WPF Application)项目,命名为:DataTracer
  2. 一个组件库(WPF User Control Library)项目,命名为:K3UcLib
  3. 一个控件库(WPF Custom Control Library)项目,命名为:K3CcLib
  4. 一个算法库(Class Library)项目,命名为:K3Helper

作为入门,这看起来有点复杂,不过实现起来还算简单。

菜单:File > New > Project…

 

菜单:File > Add > New Project…

THINKING:

通常,复杂是由简单构成的,只要我们合理的分解它;
复杂的设计,并不意味着复杂的实现;同样,简单的设计,也不意味着简单的实现;
不过,没有准备迎接复杂挑战的简单设计,却通常是小小噩梦的开始。

F5 运行,看看结果!

02. 制作一个组件

我习惯将User Control称为组件,将Custom Control称为控件。

他们的区分,简单说:User Control通常通过组合多个控件产生,Custom Control通常通过扩展单个控件产生。

现在,我们先制作一个准备用来替换现有窗口标题的组件,命名为:K3WindowHeader。

Project à Add User Control,然后修改XAML,并编译(Shift F6)

 

<Border CornerRadius="0, 0, 10, 10" Background="DarkBlue">

<DockPanel LastChildFill="True">

<Button Content="关闭" Width="75" Height="23" DockPanel.Dock="Right" />

<TextBlock Text="Window Header" DockPanel.Dock="Left" Foreground="White"/>

</DockPanel>

</Border>

这个组件包括两个控件Button,TextBlock。

CornerRadius用于设定Border四个角的弧度

= ”LeftTop, RightTop, RightBottom, LeftBottom”

DockPanel.LastChildFill,很有用的属性。

注意DockPanel所包含组件的顺序,并在组件中正确的使用DockPanel.Dock属性。

在DataTracer中使用这个组件。

Project à Add References,添加K3UcLib,然后修改MainWindow.XAML:

 

<Window …

xmlns:K3UcLib="clr-namespace:K3UcLib;assembly=K3UcLib"

WindowStyle="None"

>

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="*"/>

<RowDefinition Height="Auto"/>

</Grid.RowDefinitions>

<K3UcLib:K3WindowHeader Height="25" />

</Grid>

将WindowStyle设为None,将窗口标题隐掉,从而为DIY新的窗口标题做好准备。

Height, Width可取值包括:

Auto(自适应),*(全部剩余),NaN(相当于Auto),数值

F5 à 运行,看看结果!

这个窗口怎么关掉?Alt + F4!

这个窗口好丑!别着急,如果你真的很急,可以先试着使用 Margin属性及xxxAlignment属性,调整一下位置(试一试我的调整,如下)。

 

<Border CornerRadius="0, 0, 10, 10" Background="DarkBlue" Margin="3,0,3,0">

<DockPanel LastChildFill="True">

<Button Content="关闭" Width="75" Height="23" DockPanel.Dock="Right" Margin="0, 0, 10, 0" HorizontalAlignment="Center" VerticalAlignment="Center" />

<TextBlock Text="Window Header" DockPanel.Dock="Left" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />

</DockPanel>

</Border>

F5 à 运行,看看结果!

03. 添加事件,关闭窗口

需求:当用户点击“关闭”按钮时,关闭主窗口。

实现:为“关闭”按钮添加Click事件处理。有两种实现方式:

(1) 通过XAML文件中实现:<Button Name=”buttonClose” Content=”” …… Click=”buttonClose_Click” …… />

(2) 通过后台代码实现:this.buttonClose.Click += new new RoutedEventHandler(buttonClose_Click);

这里,我们采用后者,即后台代码方式,完整代码如下:

 

public K3WindowHeader() {

InitializeComponent();

this.Init();

}

void Init() {

this.buttonClose.Click += new RoutedEventHandler(Button_Click);

}

void Button_Click(object sender, RoutedEventArgs e) {

throw new NotImplementedException();

}

注:

使用Init()方法,是为了使代码整洁。

在你键入“+=”时,系统将为你自动生成事件代码。你可以先修改所生成的事件处理方法的名字,然后再按“TAB”键,这样就可以生成你想要的名字的方法。在这里,我将默认的buttonClose_click改为Button_Click。

接下来,我们添加事件处理的内容,以实现关闭主窗体。

注意,因为我们使用的是另一个组件项目中的组件,而非主程序自身项目中的组件,所以实现起来稍微有点麻烦,不是简单的一个Close()就可以完成。

在这种情况下,有多重实现方式:

(1) 假定组件自身知道自己是如何被使用的,如本案例中,它被放在主窗体的Grid中,那么可以这样实现:

 

((this.Parent as Grid).Parent as Window).Close();

这种实现方式,属于hard code,使组件失去了灵活性,不是一个好方法,但它是一个思路,即:只要你能找到你想要的,你就可以做你想做的。

(2) 将点击“关闭”按钮事件,转化成一个新的事件,告诉引用这个组件的窗体:有人请求关掉你!这个设计有点麻烦,但使组件具有了组件该有的特性:灵活性,或称为适应性,以保证你可以相对随意的使用它。

 

#region >>>>> 自定义事件 ...

public static readonly RoutedEvent PreviewWindowHeaderEvent;

public event RoutedEventHandler PreviewWindowHeaderEventHandler {

add { this.AddHandler(PreviewWindowHeaderEvent, value); }

remove { this.RemoveHandler(PreviewWindowHeaderEvent, value); }

}

static K3WindowHeader() {

PreviewWindowHeaderEvent = EventManager.RegisterRoutedEvent(

"PreviewWindowHeaderEventHandler",

RoutingStrategy.Tunnel,

typeof(RoutedEventHandler),

typeof(K3WindowHeader));

}

#endregion

……

void Button_Click(object sender, RoutedEventArgs e) {

RoutedEventArgs eventArgs = new RoutedEventArgs();

eventArgs.RoutedEvent = PreviewWindowHeaderEvent;

RaiseEvent(eventArgs);

}

这段代码,加在K3WindowHeader中。

#region #endregion的合理使用,有利于提升代码的可读性。你可以加上注释。BTW,我添加>>>>> … 是为了美观,读者可以试试去掉它,或改变它,看看你自己更喜欢哪一个。

注意,我添加了static 类型的构造函数,以便注册自定义事件。

Event有两种类型,其关键参数是:RoutingStrategy,其取值的不同,将生成两种传递方向不同事件。详述如下:

     
 

public static readonly RoutedEvent PreviewWindowHeaderEvent;

public event RoutedEventHandler PreviewWindowHeaderEventHandler {

add { this.AddHandler(PreviewWindowHeaderEvent, value); }

remove { this.RemoveHandler(PreviewWindowHeaderEvent, value); }

}

static MainWindow() {

PreviewWindowHeaderEvent = K3WindowHeader.PreviewWindowHeaderEvent.AddOwner(typeof(MainWindow));

}

void Init() {

this.PreviewWindowHeaderEventHandler += new RoutedEventHandler(CustomEventHandler);

}

void CustomEventHandler(object sender, RoutedEventArgs e) {

this.Close();

}

这段代码,加在DataTracer中。

注意这段代码与上段代码的不同,在于静态构造中,我们通过事件的AddOwner方法,将这两个自定义事件关联起来,从而保证了可以捕获到该事件。

同样,我使用了Init来使代码整洁,并在其中添加了对该特定事件的处理程序。别忘了将Init()放入构造函数中。

F5 à 运行,看看结果!

转载于:https://www.cnblogs.com/KingWorld/archive/2012/01/10/2317683.html

WPF教程尝试(修正部分格式)相关推荐

  1. Swift3.0语言教程使用占位符格式创建和初始化字符串

    Swift3.0语言教程使用占位符格式创建和初始化字符串 Swift3.0语言教程使用占位符格式创建和初始化字符串在很多的编程语言中都存在占位符,占位符就是为指定的内容占留一个位置.此功能一般在开发者 ...

  2. WPF DatePicker默认显示当前日期,格式化为年月日(转)

    WPF DatePicker默认显示当前日期,格式化为年月日 2018年08月08日 11:23:00 weixin_33922670 阅读数:253 原文:WPF DatePicker默认显示当前日 ...

  3. WPF教程六:布局之Grid面板(转)

    WPF教程六:布局之Grid面板 Grid:网格面板 Grid顾名思义就是"网格",以表格形式布局元素,对于整个面板上的元素进行布局,它的子控件被放在一个一个事先定义好的小格子里面 ...

  4. 计算机段落格式解释,职称计算机考试Word教程:Word段落格式

    职称计算机考试Word教程:Word段落格式 导语:段落格式是指控制段落外观的格式设置.例如,缩进.对齐.行距和分页.Word中设置行距和段间距 行距和段间距是最常用的段落格式之一. 一.内置段落样式 ...

  5. .NET WPF教程(6)——布局介绍与Canvas(①)

    从这篇文章开始是对WPF中的界面如何布局做一个较简单的介绍,大家都知道:UI是做好一个软件很重要的因素,如果没有一个漂亮的UI,功能做的再好也无法吸引很多用户使用,而且没有漂亮的界面,那么普通用户会感 ...

  6. oracle sql循环判断语句怎么写,Oracle 非常详细的 PL/SQL入门教程,PL/SQL语法格式/循环语句/条件判断/异常处理...

    PL/SQL入门教程目录 Oracle PL/SQL入门教程,PL/SQL语法格式/循环语句/条件判断/异常处理 一.PL/SQL简介 1.PL/SQL简介 1.PL/SQl是过程语言PL与结构化语言 ...

  7. YDOOK:Pydub 使用教程 打开文件 各种格式

    YDOOK:Pydub 使用教程 打开文件 各种格式 © YDOOK Jinwei Lin, shiye.work http://www.ydook.com https://orcid.org/000 ...

  8. WPF教程(四)RelativeSource属性(转)

    WPF教程(四)RelativeSource属性 2018年08月13日 15:11:56 yangwenxue1989 阅读数:749 我们进行Bingding时,如果明确知道数据源的Name,就能 ...

  9. WPF教程三:布局之WrapPanel面板(转 )

    WPF教程三:布局之WrapPanel面板 WrapPanel:环绕面板 WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列,当长度或高度不够时就会自动调整进行换行,后续排序按照从上至下 ...

最新文章

  1. keil单片机C语言输入函数,keil编写C程序是不是不能在函数内定义变量啊,求大神...
  2. 硬干货!一张图弄清楚在ESXi下如何进行网络抓包
  3. 利用http-server测试vue-cli打包后的项目
  4. python利用什么写模板_利用python自动生成verilog模块例化模板
  5. 用Linux编写简单的atm取款机系统,详细解析C++编写的ATM自动取款机模拟程序
  6. ×××购回“四不像”笔记本
  7. makefile问题:“makefile:2: *** 遗漏分隔符 。 停止。”
  8. C语言课程设计图形库
  9. matlab求条件概率密度_你真的会用程序求多重积分吗?
  10. 双线双IP和BGP双线有什么区别?
  11. 皮尔森相关系数的python实现_深入理解皮尔逊相关系数python代码
  12. html怎么混合颜色,CSS3 多色混合背景
  13. 事后诸葛亮-团队总结
  14. 彻查手机端浏览博客园出现广告一事!
  15. html基础笔记与html5代码展示
  16. linux怎么生成图形,如何在Ubuntu 16.04中创建GIF动态图片
  17. 介绍ReLU6!计算机视觉实习面经(京东/商汤/思谋/依图/图森/字节/腾讯)
  18. Cows(树状数组)
  19. 第015课 NOR Flash操作原理及裸机程序分析
  20. 【金融项目】尚融宝项目(三)

热门文章

  1. linux 用户及权限管理
  2. 编程通用知识 二叉树
  3. C++语言函数重载详解和示例
  4. redis mysql 集群_Redis(五)、Redis数据库集群相关
  5. 华为云公布2021产品上新计划,让云无处不在,让智能无所不及
  6. Docker学习总结(34)——新手使用Docker的11条准则
  7. MyBatis学习总结(3)——优化MyBatis配置文件中的配置
  8. 云linux搭建 arm开发,arm集成开发环境搭建
  9. 基 于 svm 的 图 像 分 类_CeO2和MgO助烧剂对矾土基莫来石合成料烧结的影响
  10. rabbitmq消息保证幂等的消息设计