ここの改変 stackoverflow.com
log4netの設定
<appender name="TextBoxAppender" type="{NameSpace}.{AppenderName}, {NameSpace}"> <windowName value={Name}/> //xamlのWindow x:Name="Name" <textBoxName value="{UiItemName}"/> //TextBoxとかのx:Name="UiItemName" <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level %logger - %message" /> </layout> </appender>
リンク先ではTextBoxを使用しているが、ここではListboxを使用
最初WidowNameはClassNameだと勘違いしていた...
vsが作成するxamlはWindowNameが設定されていないので注意
<Window x:Class="LogViewer.MainWindow" x:Name="{Name}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:LogViewer" mc:Ignorable="d" Title="ViewerWindow" Height="450" Width="800"> <Grid> <ListBox x:Name="LogTextBox"></ListBox> </Grid> </Window>
using log4net.Appender; using log4net.Core; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; namespace LogViewer { class WindowLogAppender : AppenderSkeleton { private ListBox AppenderTextBox { get; set; } private Window window; public string WindowName { get; set; } public string TextBoxName { get; set; } private T FindControl<T>(Control root, string textBoxName) where T : class { if (root.Name == textBoxName) { return root as T; } return root.FindName(textBoxName) as T; } protected override void Append(log4net.Core.LoggingEvent loggingEvent) { if (window == null || AppenderTextBox == null) { if (string.IsNullOrEmpty(WindowName) || string.IsNullOrEmpty(TextBoxName)) return; foreach (Window window in Application.Current.Windows) { if (window.Name == WindowName) { this.window = window; } } if (window == null) return; AppenderTextBox = FindControl<ListBox>(window, TextBoxName); if (AppenderTextBox == null) return; window.Closing += (s, e) => AppenderTextBox = null; } window.Dispatcher.BeginInvoke(new Action(delegate { AppenderTextBox.Items.Add(RenderLoggingEvent(loggingEvent)); })); } } }