来自Window Presentation Foundation Program Design的读书笔记 (第四篇 上)

本篇讲解Button and Other Controls

 

在wpf中,控件一词比早期的window from更具有意义,在早期的windows from中,屏幕上的一切都是控件,但是在wpf中这个词保留给用户交互使用。也就是说,在用户使用键盘或者鼠标时,控件会给用户一定的响应。

Control类继承自FrameworkElement:

   1:  Object
   2:      DispatherObject(abstract)
   3:        DependencyObject
   4:            Visual(abstract)
   5:                UIElement
   6:                   FrameworkElement
   7:                       Control

最经典的控件是按钮,wpf中为Button类,Button类中有个一Content的propterty和一个为Click的Event,当用户按下鼠标时就会发生事件。

一个例子:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Windows;
   6:  using System.Windows.Controls;
   7:  using System.Windows.Data;
   8:  using System.Windows.Documents;
   9:  using System.Windows.Input;
  10:  using System.Windows.Media;
  11:  using System.Windows.Media.Imaging;
  12:  using System.Windows.Navigation;
  13:  using System.Windows.Shapes;
  14:   
  15:  namespace WPF_ButtonAndControls
  16:  {
  17:      /// <summary>
  18:      /// MainWindow.xaml 的交互逻辑
  19:      /// </summary>
  20:      public partial class MainWindow : Window
  21:      {
  22:          public MainWindow()
  23:          {
  24:              InitializeComponent();
  25:              Loaded += MainWindowOnLoaded;
  26:          }
  27:   
  28:          private void MainWindowOnLoaded(object sender, RoutedEventArgs e)
  29:          {
  30:              SimpleButton();
  31:          }
  32:   
  33:          private void SimpleButton()
  34:          {
  35:              Button btn = new Button();
  36:              btn.Content = "_Click Me,Please";
  37:              btn.Click += (sender, e) =>
  38:              {
  39:                  MessageBox.Show("Hello world!");
  40:              };
  41:              Content = btn;
  42:          }
  43:      }
  44:  }

Button有一个Content属性,和window控件一样,并不是巧合,这两个类同时继承自ContentControl类,也就是定义Content property的地方。

   1:  Control
   2:      ContentControl
   3:           BaseButton(abstract)
   4:              Button
   5:           Window

这样,能够被当作Window的Content的对象都可以作为Button的Content对象来使用。

该程序开始,Button并没有焦点(input focus)的,此时的按钮并不会接受键盘事件,比如你按下空格键时,程序并没有被执行,但是你可以通过按下ALT+C组合键来触发(Trigger)按钮,当你设置Content property字符串中的某个字符前加_符号,就会让此控件具有快捷键(ALT+字符),这个特点常常用于菜单中。

你可以在代码中用如下的方式来指定某个控件具有焦点:

   1:  btn.Focus();

即使按钮没有获得焦点,但是如果你设定它为默认控件,那么它依然可以对Enter键具有反应

   1:  btn.IsDefault=true;

或者让它对Escape键有响应

   1:  btn.IsCancel=true;

ButtonBase定义了一个名为ClickMode的Property,其类别为ClickMode枚举,用来指定按钮要如何反馈鼠标点击,默认值是ClickMode.Release;如果你设定其为ClickMode.Press或者ClickMode.Hover,那么会在鼠标按下或者经过时就触发事件。

   1:   btn.ClickMode = ClickMode.Hover;

FrameworkElement控件具有margin property,我们可以用这个属性来element周围有一点空间。

   1:  btn.Margin = new Thickness(96);
现在按钮周围有1英寸的控件(wpf采用设备无关的计量单位:1/96),现在Content的文子在按钮的中间部分,我们修改一个,让它显示在按钮的左下角。
   1:  btn.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Left;
   2:  btn.VerticalContentAlignment = System.Windows.VerticalAlignment.Bottom;

我们也可以加入内边距padding,代码如下:

   1:  btn.Padding = new Thickness(48);

当然,Button的HorizontalContentAlignment和VerticalContentAlignment以及HorizontalAlignment和VerticalAlignment属性默认设置为HorizontalAlignment.Stretch和VerticalAlignment.Stretch这两个属性,这也是为什么按钮会被拉伸的原因。

现在我们删除其他的设定代码,只设定Button的HoriaontalAlignment和VerticalAlignment属性:

   1:  btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
   2:  btn.VerticalAlignment = System.Windows.VerticalAlignment.Center;

那么现在,你看到按钮已经被设定为Element的中央,并且符合Content的内容,当然你也可以插入换行符来进行测试。

另外,你也可以测试下window的SizeToContent property

   1:  SizeToContent = System.Windows.SizeToContent.WidthAndHeight;

 

当然你可以尝试的改变button的其他样式,例如

   1:  btn.Background = Brushes.CornflowerBlue;
   2:  btn.Foreground = Brushes.Yellow;
   3:  btn.BorderBrush = Brushes.Tomato;

我们来一个例子,演示button的关于MouseEnter和MouseLeave事件

   1:  private void TestButton()
   2:  {
   3:         Run runButton = null;
   4:        TextBlock tb = new TextBlock();
   5:        tb.TextAlignment = TextAlignment.Center;
   6:        tb.FontSize = 24;
   7:   
   8:        Button btn = new Button();
   9:        btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
  10:        btn.VerticalAlignment = System.Windows.VerticalAlignment.Center;
  11:         btn.MouseEnter += (sender, e) =>
  12:         {
  13:             runButton.Foreground = Brushes.Red;
  14:         };
  15:          btn.MouseLeave += (sender, e) =>
  16:          {
  17:              runButton.Foreground = SystemColors.ControlTextBrush;
  18:          };
  19:         //在textblock中加入格式化字符串
  20:         tb.Inlines.Add(new Italic(new Run("Click")));
  21:         tb.Inlines.Add(" the ");
  22:         tb.Inlines.Add(runButton = new Run("Button"));
  23:         tb.Inlines.Add(new LineBreak());
  24:         tb.Inlines.Add("to launch the ");
  25:         tb.Inlines.Add(new Bold(new Run("roket")));
  26:   
  27:         btn.Content = tb;
  28:         Content = btn;
  29:  }

我们在使用一个图片来作为按钮的Content:

   1:  Uri uri = new Uri("pack://application:,,/images/filename");
引入一个图片进入你的工程,确保图片的属性页中的build action为Resource
 
   1:          private void ImageButton()
   2:          {
   3:              Button btn = new Button();
   4:              Uri uri = new Uri("pack://application:,,/Image/word.jpg");
   5:              BitmapImage bitmap = new BitmapImage(uri);
   6:              Image img = new Image();
   7:              img.Source = bitmap;
   8:              img.Stretch = Stretch.None;
   9:              btn.Content = img;
  10:              btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
  11:              btn.VerticalAlignment = System.Windows.VerticalAlignment.Center;
  12:              Content = btn;
  13:          }
 
对于现在Content被设定为只能是唯一对象的问题我们在下一章回详细讲解,本章不再继续。
 

现在我们讲解Comand property用法,这个想法来自于用一个单一点来路由所有监听响应控件的消息。对于常见的命令,你可以将button的command property属性设置为:ApplicationCommands、ComponentCommands、MediaCommands、NavigationCommands或EditingCommands类的静态property,你可以创建自己的RouteUICommand对象。

比如说,你想要特定的按钮进行Paster命令,你可以将Command property设定为这样:

   1:  btn.Content = ApplicationCommands.Paste.Text;
   2:  btn.Command = ApplicationCommands.Paste;
我们来看一个例子:
   1:  private void ButtonCommand()
   2:  {
   3:      Title = "Command the Button";
   4:      Button btn = new Button();
   5:      btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
   6:      btn.VerticalAlignment = System.Windows.VerticalAlignment.Center;
   7:      btn.Content = ApplicationCommands.Paste.Text;
   8:      btn.Command = ApplicationCommands.Paste;
   9:   
  10:      CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste
  11:          , (sender, e) =>
  12:              {
  13:                  Title = Clipboard.GetText();
  14:              }
  15:          , (sender, e) =>
  16:          {
  17:              e.CanExecute = Clipboard.ContainsText();
  18:          }));
  19:      Content = btn;
  20:  }

这个例子演示了一个button如何使用Command property,在UEElement类中定义了一个CommandBindings属性,我们使用了window类的Commandbindings property。这个例子中的Clipboard类属于System.Window命名空间,你可以复制一段文字,然后查看具体效果,然后在复制一张图片,在查看具体效果,你会发现,复制一张图片时,按钮会被禁用,这就是第二个事件中的e.CanExecute被设为false的原因,程序会自动判断,然后改变button的IsEnabled property,这就是使用Command propery的好处之一。

CheckBox和RadioButton都被认为是切换(toggle)按钮,这一点可以从继承树中查看。

   1:  Control
   2:     ContentControl
   3:         ButtonBase(abstract)
   4:            Button
   5:               GridViewColumnHeader
   6:                  RepeatButton
   7:                      ToggleButton
   8:                         CheckBox
   9:                         RadioButton
 

ToggleButton并不是抽象类,所以我们可以建立它的对象,它看起来和普通按钮一样,但是它具有on和off的切换,看一个例子:

   1:  private void ToggleButtonExmple()
   2:  {
   3:      ToggleButton tb = new ToggleButton();
   4:      tb.Content = "Can _Resize";
   5:      tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
   6:      tb.VerticalAlignment = System.Windows.VerticalAlignment.Center;
   7:      tb.IsChecked = (ResizeMode == System.Windows.ResizeMode.CanResize);
   8:      tb.Checked += TbOnCheck;
   9:      tb.Unchecked += TbOnCheck;
  10:      Content = tb;
  11:  }
  12:   
  13:  private void TbOnCheck(object sender,RoutedEventArgs e)
  14:  {
  15:      ToggleButton btn = sender as ToggleButton;
  16:      ResizeMode = (bool)btn.IsChecked ? ResizeMode.CanResize : System.Windows.ResizeMode.NoResize;
  17:  }

ToggleButton在这里不用来控制窗体的ResizeMode属性,在ResizeMode.CanResize和ResizeMode.NoResize中来回切换。

如果将ToggleButton的IsThreeState property设置为True,那么你可以使用ToggleButton的第三种状态null用来表示不确定的状态。

ToggleButton和CheckBox本质上都是代表bool值的,如果让togglebutton来和某个对象的某个bool值属性相关联是有意义的,这就被称为属性绑定,调用的方法:

   1:  tb.SetBinding(ToggleButton.IsCheckedProperty, "smoeproperty");

第二个参数是字符串,是你想要和按钮的IsCheck产生相关联的property名,你用button的datacontext property来指定someproperty的所属对象。

      我们来修改上面的例子:

   1:  private void ToggleButtonExmple()
   2:  {
   3:      ToggleButton tb = new ToggleButton();
   4:      tb.Content = "Can _Resize";
   5:      tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
   6:      tb.VerticalAlignment = System.Windows.VerticalAlignment.Center;
   7:      //tb.IsChecked = (ResizeMode == System.Windows.ResizeMode.CanResize);
   8:      //tb.Checked += TbOnCheck;
   9:      //tb.Unchecked += TbOnCheck;
  10:      tb.SetBinding(ToggleButton.IsCheckedProperty, "Topmost");
  11:      tb.DataContext = this;
  12:      Content = tb;
  13:  }

这里我们让togglebutton和window的Topmost property属性关联,Topmost属性为True是,可以使window始终据与顶层,当你点击button的时候,这个属性也在随之改变。

在System.windows.Data命名空间中包含着一个叫Binding的类,你可以用这个类来设置属性绑定:

   1:  Binding bind = new Binding("Tommost");
   2:  bind.Source = this;
   3:  tb.SetBinding(ToggleButton.IsCheckedProperty, bind);

转载于:https://www.cnblogs.com/freedoom/archive/2012/10/29/2744236.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值