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>
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>
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的发布与回调就这样串起来了。
如果转载,请注明出处。https://www.cnblogs.com/ssdq/