实现结果
一,首先建立一个UserControl
前台代码如下:
点击查看代码
<UserControl x:Class="实现一个错误信息栏.ErrorLog"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:实现一个错误信息栏"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><TextBox x:Name="ErrorTextBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding LogStr}" Foreground="Red" Margin="0" Padding="0" IsReadOnly="True" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" FontSize="14" FontWeight="DemiBold" TextChanged="ErrorTextBox_TextChanged" ></TextBox></Grid>
</UserControl>
后台代码如下:
点击查看代码
/// <summary>
/// ErrorLog.xaml 的交互逻辑
/// </summary>
public partial class ErrorLog : UserControl
{public ErrorLog(){InitializeComponent();this.DataContext= ErrorLogViewModel.Instance;}private void ErrorTextBox_TextChanged(object sender, TextChangedEventArgs e){var textBox = sender as TextBox;if (textBox != null){// 滚动到 TextBox 的最下方textBox.ScrollToEnd();}}
}
二,然后建立一个类,用来作以上控件的上下文
完整代码如下:
点击查看代码
public class ErrorLogViewModel : INotifyPropertyChanged
{#region 做成单例模式public static ErrorLogViewModel _Instance;public static ErrorLogViewModel Instance{get{if (_Instance == null)_Instance = new ErrorLogViewModel();return _Instance;}}private ErrorLogViewModel() { }#endregion//最大字符长度int maxMsgLength = 5000;public void AddLogStr(string str){var msg = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss:fff}] {str}\r\n";LogStr += msg;if(LogStr.Length > maxMsgLength){LogStr = LogStr.Substring(LogStr.Length - maxMsgLength);}}private string _LogStr;public string LogStr{get { return _LogStr; }set { _LogStr = value; OnPropertyChange("LogStr"); }}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChange(string propertyName){if (PropertyChanged != null){PropertyChanged(this, new PropertyChangedEventArgs(propertyName));}}
}
这里主要继承了一个接口INotifyPropertyChanged,用来通知前台数据已改变。然后做成单例模式是为了确保只有一个实例,该实例就是绑定到UserControl并且充当其上下文的实例,这样在其他地方产生的错误信息才能展示在UserControl前台。然后提供了一个AddLogStr方法,供其他地方调用来输入错误信息。
三,建一个页面测试该控件
前台代码:
点击查看代码
<Grid><Grid.RowDefinitions><RowDefinition Height="7*"/><RowDefinition Height="3*"/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="2*"/><ColumnDefinition Width="8*"/></Grid.ColumnDefinitions><!--建一个按钮来生成错误信息--><Button Grid.Column="0" Grid.Row="1" Click="Button_Click" Content="生成错误信息"/><local:ErrorLog Grid.Column="1" Grid.Row="1"/></Grid>
后台代码:
点击查看代码
public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){ErrorLogViewModel.Instance.AddLogStr($"新的错误信息+{DateTime.Now}");}}
我这里通过按钮来生成错误信息,只是举一个例子,错误信息可能在程序运行的任一模块产生,然后在相应的地方调用生成错误的方法就可以展示在界面了。