WPF程序设计 :第四章 按钮与其他控件(Buttons and Other Controls)

WPF中,控件(Control)一词的意义,比早期Windows编程的控件,有更特定的含义。

比方说,在WinForms应用程序中,屏幕上出现的一切,都被视为控件。在WPF中,这个词保留给用户交互使用,也就是说,当用户用鼠标或是键盘时,控件一般会对用户提供某种响应(feedback)。前章的TextBlock、Image和Shape元素,都会接收键盘、但是它们都选择忽略,控件会主动监视并处理用户的输入。

Control 类直接继承自 FrameworkElement:

Object

      DispatcherObject(abstract)

             DependencyObject

                       Visual(abstract)

                                  UIElement

                                          FrameworkElement

                                                  Control

Window 继承自Control,中间还有个ContentControl,你自己知道ContentControl继承自Control,Control是继承自FrameworkElement。Control所定义的property包括Background、BorderBrush、BorderThickness以及和font相关的property,例如FontWeight和FontStretch。(注意的是:虽然TextBlock也具有许多font property,但是TextBlock不是继承自Control。TextBlock的这些property是自己定义的。)

 

从Control继承而来的类超过了50个,这些类提供给程序员各式各样的控件,包括按钮、列表框(list box)、滚动条(scroll bar)、编辑框(edit field)、菜单(menu)和工具条(toolbar)。这些类都是放在System.Windows.Controls与System.Windows.Controls.Primitives命名空间中的。这些命名空间也包含一些不是继承自Control的类。

最为经典的控件是Button按钮,在WPF中是Button类。Button类有一个Content 的property以及一个名为Click的事件。当用户用鼠标按下按钮,就会发生事件。

 

实例程序 - 1

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace PartFour
{
    
class ClickTheButton : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new ClickTheButton());
        }
        
public ClickTheButton()
        {
            Title 
= "Click the Button";
            Button btn 
= new Button();
            btn.Content 
= "_Click me, please!";
            btn.Click 
+= new RoutedEventHandler(btn_Click);
            btn.Margin 
= new Thickness(100);
            btn.Height 
= 300;
            btn.Width 
= 300;
            btn.HorizontalContentAlignment 
= HorizontalAlignment.Left;
            btn.VerticalContentAlignment 
= VerticalAlignment.Bottom;

            btn.HorizontalAlignment 
= HorizontalAlignment.Left;
            btn.VerticalAlignment 
= VerticalAlignment.Bottom;
            Content 
= btn;
            SizeToContent 
= SizeToContent.WidthAndHeight;
        }

        
void btn_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(
"The button has been Clicked and all is well.", Title);
        }
    }
}

 Button有一个Content property,这一点和Window一样,且并非巧合。这两个类(以及一些其他的类)都是继承自ContentControl的类,也就是定义了Content property的地方。

下面是Control以下的局部类层次图:

         Control

              ContentControl

                    ButtonBase(abstract)

                         Button

                    Window

 

Window与Button否有相同的 Content property.

 

btn.IsDefault = true;  等价于 btn.Focus();按钮作为默认按钮,也就是焦点。

 

或则让它可以对Escape键有反应,做法如下: btn.IsCancel = true;

 

实例程序 - 2:

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace PartFour
{
    
public class FormatTheButton : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new FormatTheButton());
        }

        Run runButton;

        
public FormatTheButton()
        {
            Title 
= "Format the Button";

            
// 建立一个按钮,将其设置成窗体的Content
            Button btn = new Button();
            btn.HorizontalAlignment 
= HorizontalAlignment.Center;
            btn.VerticalAlignment 
= VerticalAlignment.Center;
            btn.MouseEnter 
+= new System.Windows.Input.MouseEventHandler(btn_MouseEnter);
            btn.MouseLeave 
+= new System.Windows.Input.MouseEventHandler(btn_MouseLeave);
            Content 
= btn;

            
// 建立一个Textblock,将它设置成按钮的内容
            TextBlock txtblk = new TextBlock();
            txtblk.FontSize 
= 24;
            txtblk.TextAlignment 
= TextAlignment.Center;
            btn.Content 
= txtblk;

            
// 在TextBlock中加入格式文本
            txtblk.Inlines.Add(new Italic(new Run("Click")));
            txtblk.Inlines.Add(
" the");
            txtblk.Inlines.Add(runButton 
= new Run(" Button"));
            txtblk.Inlines.Add(
new LineBreak());
            txtblk.Inlines.Add(
" to launch the ");
            txtblk.Inlines.Add(
new Bold(new Run("rocket")));
        }

        
void btn_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            runButton.Foreground 
= Brushes.Red;
        }

        
void btn_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            runButton.Foreground 
= SystemColors.ControlTextBrush;
        }
    }
}

注意,在该程序中,包含单词"button"的Run对象被存储在一个名为runButton的变量中,当鼠标进入按钮区域时,Run对象的前景色上红色。当鼠标离开按钮区域时,颜色恢复默认值(SystemColors。ControlTextBrush)。

实例程序 - 3:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Media;

namespace PartFour
{
    
public class ImageTheButton : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new ImageTheButton());
        }

        
public ImageTheButton()
        {
            Title 
= "Image the Button";

            Uri uri 
= new Uri(@"D:/MyFace.jpg");

            BitmapImage bitmap 
= new BitmapImage(uri);
            Image img 
= new Image();
            img.Source 
= bitmap;
            img.Stretch 
= Stretch.None;

            Button btn 
= new Button();
            btn.Content 
= img;

            btn.HorizontalAlignment 
= HorizontalAlignment.Center;
            btn.VerticalAlignment 
= VerticalAlignment.Center;

            Content 
= btn; 
        }
    }
}

-----

Command property,ButtonBase类和其他的类(包括MenuItem)定义了这个property,对于常见的命名,你会将Button的Command property设置为ApplicationCommands、ComponentCommands、MediaCommands、NavigationCommads或EditingCommands类的静态property。前面4个类属于System.Windows.Input命名空间;后面一个是在System.Windows.Documents命名空间。这些类的静态property是属于RoutedUICommand类型。你可以创建你自己的RoutedUICommand类型的对象。

比方说,如果你想要特定的按钮,以进行一个Paste命名,你可以将Command property设置成:

btn.Command = ApplicationCommands.Paste;

现在,你需要将此特定的Paste命令与事件处理器关联起来。这样的关联方法称为绑定(binding),这是WPF数种binding中的一种.UIElement类定义一个名为CommandBindings(复数)的Property(且Control和Window类继承此property),这是CommanBinding对象的集合(collection)。你可能用窗口的CommandBinding集合:

      CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste), PasteOnExecute, PasteCanExecute));

具体可参加如下程序:

实例程序 - 4:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace PartFour
{
    
public class CommandTheButton : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new CommandTheButton());
        }

        
public CommandTheButton()
        {
            Title 
= "Command The Button!";
            
            
// 建立按钮,并将其设置成窗体的内容
            Button btn = new Button();
            btn.HorizontalAlignment 
= HorizontalAlignment.Center;
            btn.VerticalAlignment 
= VerticalAlignment.Center;
            btn.Command 
= ApplicationCommands.Paste;
            btn.Content 
= ApplicationCommands.Paste.Text;
            Content 
= btn;

            
// 将此命令绑定到事件处理器
            CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, PasteOnExecute, PasteCanExecute));
        }

        
void PasteOnExecute(object sender, ExecutedRoutedEventArgs ards)
        {
            Title 
= Clipboard.GetText();
        }

        
void PasteCanExecute(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute 
= Clipboard.ContainsText();
        }

        
protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            
base.OnMouseDown(e);
            Title 
= "Command The Button!";
        }
    }
}

-------

切换按钮,CheckBox和RadioButton都被认为是"切换"(toggle)按钮,这一点从它们的继承结构就可以轻易看出来:

      Control

         ContentControl

              ButtonBase(abstract)

                     Button

                     GridViewColumnHeader

                     RequestButton

                     ToggleButton

                               CheckBox

                               RadioButton

 

   ToggleButton不是抽象类,所以你可以创建它的对象。它看起来就像一个常规的按钮,不同之处在于,他可以有On和Off切换。

实例程序 - 5:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls.Primitives;

namespace PartFour
{
    
public class ToggleTheButton : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new ToggleTheButton());
        }

        
public ToggleTheButton()
        {
            Title
="ToggleTheButton";

            ToggleButton btn 
= new ToggleButton();
            btn.Content 
= "Can_Resize";

            btn.HorizontalAlignment 
= HorizontalAlignment.Center;
            btn.VerticalAlignment 
= VerticalAlignment.Center;
            
            btn.IsChecked 
= (ResizeMode == ResizeMode.CanResize);
            btn.Checked 
+= new RoutedEventHandler(btn_Checked);
            btn.Unchecked 
+= new RoutedEventHandler(btn_Checked);
            Content 
= btn;
        }

        
void btn_Checked(object sender, RoutedEventArgs e)
        {
            ToggleButton btn 
= sender as ToggleButton;
            ResizeMode 
= (bool)btn.IsChecked ? ResizeMode.CanResize : ResizeMode.NoResize;
        }
    }
}

见下面程序:

实例程序 - 6:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Imaging;

namespace PartFour
{
    
public class BindTheButton : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new BindTheButton());
        }

        
public BindTheButton()
        {
            Title 
= "Bind the Button !";
            Topmost 
= true;
            ToggleButton btn 
= new ToggleButton();
            btn.Content 
= "Make_Topmost";
            btn.HorizontalAlignment 
= HorizontalAlignment.Center;
            btn.VerticalAlignment 
= VerticalAlignment.Center;
            btn.SetBinding(ToggleButton.IsCheckedProperty, 
"Topmost");
            btn.DataContext 
= this;
            Content 
= btn;

            
//Binding bind = new Binding("Topmost");
            
//bind.Source = this;
            
//btn.SetBinding(ToggleButton.IsCheckedProperty, bind);
            
// 这个Binding类让你在定义数据绑定时有更过的选择

            Uri uri 
= new Uri(@"D:/MyFace.jpg");
            BitmapImage bitmap 
= new BitmapImage(uri);
            Image img 
= new Image();
            img.Source 
= bitmap;

            ToolTip tip 
= new ToolTip();
            tip.Content 
= img;//"Toogle the button on to make the window topmost on the desktop";
            btn.ToolTip = tip;

        }
    }
}

-----

TextBox控件:

       Control

             TextBoxBase(abstract)

                      TextBox

                      RichTextBox    

 

  实例程序 - 7:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace PartFour
{
    
class UriDialog : Window
    {
        TextBox txtbox;

        
public UriDialog()
        {
            Title 
= "Enter a URI";
            ShowInTaskbar 
= false;
            SizeToContent 
= SizeToContent.WidthAndHeight;
            WindowStyle 
= WindowStyle.ToolWindow;

            WindowStartupLocation 
= WindowStartupLocation.CenterOwner;

            txtbox 
= new TextBox();
            txtbox.Margin 
= new Thickness(48);
            Content 
= txtbox;

            txtbox.Focus();
        }

        
public string Text
        {
            
set {
                txtbox.Text 
= value;
                txtbox.SelectionStart 
= txtbox.Text.Length;
            }
            
get {
                
return txtbox.Text;
            }
        }

        
protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            
if (e.Key == Key.Enter)
                Close();
        }
    }

    
class NavigateTheWeb : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new NavigateTheWeb ());
        }

        Frame frm;
        
public NavigateTheWeb()
        {
            Title 
= "Navigate the Web";

            frm 
= new Frame();

            Content 
= frm;

            Loaded 
+= new RoutedEventHandler(NavigateTheWeb_Loaded);
        }

        
void NavigateTheWeb_Loaded(object sender, RoutedEventArgs e)
        {
            UriDialog dlg 
= new UriDialog();
            dlg.Owner 
= this;
            dlg.Text 
= "http://";

            dlg.ShowDialog();

            
try
            {
                frm.Source 
= new Uri(dlg.Text);
            }
            
catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Title);
            }
        }
    }
}

实例程序 - 8:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.IO;
using System.Windows.Controls;
using System.Windows.Input;

namespace PartFour
{
    
class EditSomeText : Window
    {
        [STAThread]
        
public static void Main()
        {
            Application app 
= new Application();
            app.Run(
new EditSomeText());
        }

        
static string strFileName = @"D:/EditSomeText.txt";
        
//Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "EditSomeText/EditSomeText.txt");

        TextBox txtbox;

        
public EditSomeText()
        {
            Title 
= "Edit Some Text";

            
// 建立 text box
            txtbox = new TextBox();
            txtbox.AcceptsReturn 
= true;
            txtbox.TextWrapping 
= TextWrapping.Wrap;
            txtbox.VerticalScrollBarVisibility 
= ScrollBarVisibility.Auto;
            txtbox.KeyDown 
+= new System.Windows.Input.KeyEventHandler(txtbox_KeyDown);

            Content 
= txtbox;

            
try
            {
                txtbox.Text 
= File.ReadAllText(strFileName);
            }
            
catch
            { 
            }

            txtbox.CaretIndex 
= txtbox.Text.Length;
            txtbox.Focus();
        }

        
void txtbox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            
if (e.Key == Key.F5)
            {
                txtbox.SelectedText 
= DateTime.Now.ToString();
                txtbox.CaretIndex 
= txtbox.SelectionStart + txtbox.SelectionLength;
            }
        }

        
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            
try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(strFileName));
                File.WriteAllText(strFileName, txtbox.Text);
            }
            
catch (Exception ex)
            {
                MessageBoxResult result 
= MessageBox.Show("sffss" + ex.Message, Title, MessageBoxButton.YesNo, MessageBoxImage.Exclamation);

                e.Cancel 
= (result == MessageBoxResult.No);
            }
        }
    }
}

 

原文地址:https://www.cnblogs.com/Dlonghow/p/1287641.html