WPF中使用EventHandler更新UI内容

在WPF中,EventHandler类似于一套订阅与发布的操作。甲方提供一个event的回调注册入口让乙方来订阅自己发布的event。这么理解起来就是需要发布消息的一方定义event(就像是C语言里面定义了一个全局的回调函数指针变量),需要订阅event的一方就注册一个回调函数(就好像C语言里面对全局函数指针变量赋值)。

下面来一套演示代码,涉及两个窗口。

第一个是主窗口,提供一个textblock控件和一个按钮控件。代码如下:

 1 <Window x:Class="EvtHdlrTest.SubEditWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:EvtHdlrTest"
 7         mc:Ignorable="d"
 8         Title="SubEditWindow" Height="240" Width="320">
 9     <Grid>
10         <Grid.RowDefinitions>
11             <RowDefinition Height="4*"/>
12             <RowDefinition Height="*"/>
13         </Grid.RowDefinitions>
14         <Grid.ColumnDefinitions>
15             <ColumnDefinition Width="*"/>
16             <ColumnDefinition Width="*"/>
17         </Grid.ColumnDefinitions>
18         <TextBox x:Name="CtrlTextBox" Margin="5,5,5,5" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" VerticalScrollBarVisibility="Auto" Background="Yellow" FontSize="18" FontWeight="Bold"></TextBox>
19         <Button x:Name="CtrlButtonCommit" Margin="5,5,5,5" Grid.Row="1" Grid.Column="0" Click="CtrlButtonCommit_Click" Background="Green">提交给主窗口</Button>
20         <Button x:Name="CtrlButtonClose" Margin="5,5,5,5" Grid.Row="1" Grid.Column="1" Click="CtrlButtonClose_Click" Background="Red">关闭本窗口</Button>
21     </Grid>
22 </Window>
子窗口布局XML
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Shapes;
14 
15 namespace EvtHdlrTest
16 {
17     /// <summary>
18     /// SubEditWindow.xaml 的交互逻辑
19     /// </summary>
20     public partial class SubEditWindow : Window
21     {
22         public event EventHandler<string>? SubWindowTextChangedEventHandler;
23 
24         public SubEditWindow()
25         {
26             InitializeComponent();
27         }
28 
29         public SubEditWindow(string s) : this()
30         {
31             CtrlTextBox.AppendText("从主窗口带来了如下字符串:\n" + s);
32             CtrlTextBox.ScrollToEnd();
33         }
34 
35         private void CtrlButtonCommit_Click(object sender, RoutedEventArgs e)
36         {
37             SubWindowTextChangedEventHandler?.Invoke(this, CtrlTextBox.Text);
38             CtrlButtonCommit.IsEnabled = false;
39         }
40 
41         private void CtrlButtonClose_Click(object sender, RoutedEventArgs e)
42         {
43             this.Close();
44         }
45     }
46 }
子窗口类实现

 

第二个是子窗口,提供一个textbox控件和两个按钮控件。代码如下:

 1 <Window x:Class="EvtHdlrTest.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:EvtHdlrTest"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="240" Width="400">
 9     <Grid>
10         <Grid.RowDefinitions>
11             <RowDefinition Height="4*"/>
12             <RowDefinition Height="*"/>
13         </Grid.RowDefinitions>
14         <ScrollViewer x:Name="CtrlTextScroller"  Grid.Row="0" VerticalScrollBarVisibility="Visible">
15             <TextBlock x:Name="CtrlTextBlock" Margin="5,5,5,5" />
16         </ScrollViewer>
17         <Button x:Name="CtrlButton" Margin="5,5,5,5" Grid.Row="1" Click="CtrlButton_Click">弹出新编辑窗</Button>
18     </Grid>
19 </Window>
主窗口布局XML
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace EvtHdlrTest
17 {
18     /// <summary>
19     /// Interaction logic for MainWindow.xaml
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26             CtrlTextBlock.Text = "这些文字全部传给子窗口去编辑吧。";
27         }
28 
29         private void CtrlButton_Click(object sender, RoutedEventArgs e)
30         {
31             string s = System.DateTime.Now.ToString("hh:mm:ss\n") + CtrlTextBlock.Text;
32             SubEditWindow sw = new SubEditWindow(s);
33             sw.SubWindowTextChangedEventHandler += TextFromSubWindow;
34             sw.Show();
35         }
36 
37         private void TextFromSubWindow(object? sender, string s)
38         {
39             CtrlTextBlock.Text = s;
40             CtrlTextScroller.ScrollToBottom();
41         }
42     }
43 }
主窗口类实现

 

实测截图:

 

 

 

子窗口类里面定义了一个EventHandler成员变量:

namespace EvtHdlrTest
{
    public partial class SubEditWindow : Window
    {
        public event EventHandler<string>? SubWindowTextChangedEventHandler;
    }
}

主窗口中将子窗口的EventHandler成员变量追加了一个值:

string s = System.DateTime.Now.ToString("hh:mm:ss\n") + CtrlTextBlock.Text;
SubEditWindow sw = new SubEditWindow(s);
sw.SubWindowTextChangedEventHandler += TextFromSubWindow;
sw.Show();

最后子窗口点击按钮发出event:

private void CtrlButtonCommit_Click(object sender, RoutedEventArgs e)
{
    SubWindowTextChangedEventHandler?.Invoke(this, CtrlTextBox.Text);
    CtrlButtonCommit.IsEnabled = false;
}

主窗口监听到event执行了回调:

private void TextFromSubWindow(object? sender, string s)
{
    CtrlTextBlock.Text = s;
    CtrlTextScroller.ScrollToBottom();
}

整个Event的发布与回调就这样串起来了。

posted @ 2022-12-30 16:07  -ssdq-  阅读(308)  评论(0编辑  收藏  举报