Working with warnings

This commit is contained in:
Matthias Heil
2026-04-04 15:36:30 +02:00
parent 3b9d8f4c16
commit 015d7d4542
21 changed files with 211 additions and 159 deletions
@@ -10,7 +10,7 @@
</Application.DataTemplates> </Application.DataTemplates>
<Application.Styles> <Application.Styles>
<FluentTheme Mode="Light"/> <FluentTheme/>
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>
@@ -1,23 +1,23 @@
using System;
using System.Drawing;
using System.Reflection;
using System.Threading;
using Avalonia; using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using AvaloniaLoggingDI.ViewModels; using AvaloniaLoggingDI.ViewModels;
using AvaloniaLoggingDI.Views; using AvaloniaLoggingDI.Views;
using LogViewer.Avalonia; using LogViewer.Avalonia;
using MessageBox.Avalonia;
using MessageBox.Avalonia.Enums;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using MsLogger.Core; using MsLogger.Core;
using RandomLogging.Service; using RandomLogging.Service;
using Icon = MessageBox.Avalonia.Enums.Icon; using System;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Threading;
using Icon = MsBox.Avalonia.Enums.Icon;
namespace AvaloniaLoggingDI; namespace AvaloniaLoggingDI;
@@ -30,9 +30,9 @@ public partial class App : Application
{ {
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{ {
// Line below is needed to remove Avalonia data validation. // Avoid duplicate validations from both Avalonia and the CommunityToolkit.
// Without this line you will get duplicate validations from both Avalonia and CT // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
ExpressionObserver.DataValidators.RemoveAll(x => x is DataAnnotationsValidationPlugin); DisableAvaloniaDataAnnotationValidation();
// catch all unhandled errors // catch all unhandled errors
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
@@ -119,7 +119,17 @@ public partial class App : Application
base.OnFrameworkInitializationCompleted(); base.OnFrameworkInitializationCompleted();
} }
private static void DisableAvaloniaDataAnnotationValidation()
{
// Get an array of plugins to remove
var dataValidationPluginsToRemove = BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
// remove each entry found
foreach (var plugin in dataValidationPluginsToRemove)
{
BindingPlugins.DataValidators.Remove(plugin);
}
}
private void OnShutdownRequested(object? sender, ShutdownRequestedEventArgs e) private void OnShutdownRequested(object? sender, ShutdownRequestedEventArgs e)
=> _ = _host!.StopAsync(_cancellationTokenSource!.Token); => _ = _host!.StopAsync(_cancellationTokenSource!.Token);
@@ -133,19 +143,22 @@ public partial class App : Application
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
=> ShowMessageBox("Unhandled Error", ((Exception)e.ExceptionObject).Message); => ShowMessageBox("Unhandled Error", ((Exception)e.ExceptionObject).Message);
private void ShowMessageBox(string title, string message) private static void ShowMessageBox(string title, string message)
{ {
MessageBox.Avalonia.BaseWindows.Base.IMsBoxWindow<ButtonResult> messageBoxStandardWindow = MessageBoxManager var box = MessageBoxManager.GetMessageBoxStandard(
.GetMessageBoxStandardWindow(title, message, ButtonEnum.Ok, Icon.Stop); "Exception",
text: message,
messageBoxStandardWindow.Show(); ButtonEnum.Ok,
Icon.Stop
);
_ = box.ShowAsync().GetAwaiter();
} }
private void LogStartingMode() private void LogStartingMode()
{ {
// Get the Launch mode // Get the Launch mode
bool isDevelopment = string.Equals(Environment.GetEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES"), "debug", bool isDevelopment = string.Equals(Environment.GetEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES"), "debug",
StringComparison.InvariantCultureIgnoreCase); StringComparison.OrdinalIgnoreCase);
// initialize a logger & EventId // initialize a logger & EventId
ILogger<App> logger = _host!.Services.GetRequiredService<ILogger<App>>(); ILogger<App> logger = _host!.Services.GetRequiredService<ILogger<App>>();
@@ -4,6 +4,9 @@
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="Assets\avalonia-logo.ico" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="appsettings.Development.json"> <Content Include="appsettings.Development.json">
@@ -31,4 +34,8 @@
<ProjectReference Include="..\..\Core\MsLogger.Core\MsLogger.Core.csproj" /> <ProjectReference Include="..\..\Core\MsLogger.Core\MsLogger.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\avalonia-logo.ico" />
</ItemGroup>
</Project> </Project>
@@ -2,15 +2,24 @@ using Avalonia.Controls;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using AvaloniaLoggingDI.ViewModels; using AvaloniaLoggingDI.ViewModels;
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace AvaloniaLoggingDI; namespace AvaloniaLoggingDI;
// <summary>
/// Given a view model, returns the corresponding view if possible.
/// </summary>
[RequiresUnreferencedCode(
"Default implementation of ViewLocator involves reflection which may be trimmed away.",
Url = "https://docs.avaloniaui.net/docs/concepts/view-locator")]
public class ViewLocator : IDataTemplate public class ViewLocator : IDataTemplate
{ {
public IControl Build(object data) public Control? Build(object? param)
{ {
string name = data.GetType().FullName!.Replace("ViewModel", "View"); if (param is null)
Type? type = Type.GetType(name); return null;
var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);
var type = Type.GetType(name);
if (type != null) if (type != null)
{ {
@@ -20,7 +29,7 @@ public class ViewLocator : IDataTemplate
return new TextBlock { Text = "Not Found: " + name }; return new TextBlock { Text = "Not Found: " + name };
} }
public bool Match(object data) public bool Match(object? data)
{ {
return data is ViewModelBase; return data is ViewModelBase;
} }
@@ -11,7 +11,7 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
Title="C# AVALONIA | LogViewer Control Example - Dot Net 7.0" Title="C# AVALONIA | LogViewer Control Example - Dot Net 7.0"
Icon="avares://Avalonia.Resources/Assets/avalonia-logo.ico" Icon="/Assets/avalonia-logo.ico"
WindowStartupLocation="CenterScreen" Height="634" Width="600"> WindowStartupLocation="CenterScreen" Height="634" Width="600">
<control:LogViewerControl DataContext="{Binding LogViewer}" /> <control:LogViewerControl DataContext="{Binding LogViewer}" />
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Styles> <Application.Styles>
<FluentTheme Mode="Light"/> <FluentTheme/>
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>
@@ -4,6 +4,7 @@ using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using AvaloniaLoggingNoDI.Views; using AvaloniaLoggingNoDI.Views;
using System.Linq;
namespace AvaloniaLoggingNoDI; namespace AvaloniaLoggingNoDI;
@@ -18,12 +19,24 @@ public partial class App : Application
{ {
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{ {
// Line below is needed to remove Avalonia data validation. // Avoid duplicate validations from both Avalonia and the CommunityToolkit.
// Without this line you will get duplicate validations from both Avalonia and CT // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
ExpressionObserver.DataValidators.RemoveAll(x => x is DataAnnotationsValidationPlugin); DisableAvaloniaDataAnnotationValidation();
desktop.MainWindow = new MainWindow(); desktop.MainWindow = new MainWindow();
} }
base.OnFrameworkInitializationCompleted(); base.OnFrameworkInitializationCompleted();
} }
private static void DisableAvaloniaDataAnnotationValidation()
{
// Get an array of plugins to remove
var dataValidationPluginsToRemove =
BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
// remove each entry found
foreach (var plugin in dataValidationPluginsToRemove)
{
BindingPlugins.DataValidators.Remove(plugin);
}
}
} }
@@ -6,6 +6,14 @@
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="Assets\avalonia-logo.ico" />
</ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\avalonia-logo.ico" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="appsettings.Development.json"> <Content Include="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -11,7 +11,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="C# AVALONIA MINIMAL | LogViewer Control Example - Dot Net 7.0" Title="C# AVALONIA MINIMAL | LogViewer Control Example - Dot Net 7.0"
Icon="avares://Avalonia.Resources/Assets/avalonia-logo.ico" Icon="/Assets/avalonia-logo.ico"
WindowStartupLocation="CenterScreen" Height="634" Width="600"> WindowStartupLocation="CenterScreen" Height="634" Width="600">
<control:LogViewerControl x:Name="LogViewerControl" /> <control:LogViewerControl x:Name="LogViewerControl" />
@@ -8,7 +8,7 @@
</Application.DataTemplates> </Application.DataTemplates>
<Application.Styles> <Application.Styles>
<FluentTheme Mode="Light"/> <FluentTheme />
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>
@@ -1,6 +1,5 @@
using Avalonia; using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using AvaloniaSerilogDI.ViewModels; using AvaloniaSerilogDI.ViewModels;
@@ -8,20 +7,20 @@ using AvaloniaSerilogDI.Views;
using Common.Core.Extensions; using Common.Core.Extensions;
using LogViewer.Avalonia; using LogViewer.Avalonia;
using LogViewer.Core; using LogViewer.Core;
using MessageBox.Avalonia;
using MessageBox.Avalonia.Enums;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using RandomLogging.Service; using RandomLogging.Service;
using Serilog; using Serilog;
using Serilog.Sinks.LogView.Core; using Serilog.Sinks.LogView.Core;
using System; using System;
using System.Drawing; using System.Globalization;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using Icon = MessageBox.Avalonia.Enums.Icon; using Icon = MsBox.Avalonia.Enums.Icon;
namespace AvaloniaSerilogDI; namespace AvaloniaSerilogDI;
public partial class App : Application public partial class App : Application
@@ -46,10 +45,9 @@ public partial class App : Application
{ {
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{ {
// Line below is needed to remove Avalonia data validation. // Avoid duplicate validations from both Avalonia and the CommunityToolkit.
// Without this line you will get duplicate validations from both Avalonia and CT // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
ExpressionObserver.DataValidators.RemoveAll(x => x is DataAnnotationsValidationPlugin); DisableAvaloniaDataAnnotationValidation();
// catch all unhandled errors // catch all unhandled errors
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
@@ -78,43 +76,11 @@ public partial class App : Application
services.AddLogging(configure: cfg => services.AddLogging(configure: cfg =>
{ {
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
//Serilog.Core.Logger logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration) .ReadFrom.Configuration(builder.Configuration)
.WriteTo.DataStoreLoggerSink( .WriteTo.DataStoreLoggerSink( dataStoreProvider: () => _host!.Services.TryGetService<ILogDataStore>()!,formatProvider: CultureInfo.InvariantCulture)
dataStoreProvider: () => _host!.Services.TryGetService<ILogDataStore>()!
//dataStoreProvider: () => _host!.Services.TryGetService<ILogDataStore>()!,
//options =>
//{
// options.Colors[LogLevel.Trace] = new()
// {
// Foreground = Color.White,
// Background = Color.DarkGray
// };
// options.Colors[LogLevel.Debug] = new()
// {
// Foreground = Color.White,
// Background = Color.Gray
// };
// options.Colors[LogLevel.Information] = new()
// {
// Foreground = Color.White,
// Background = Color.DodgerBlue
// };
// options.Colors[LogLevel.Warning] = new()
// {
// Foreground = Color.White,
// Background = Color.Orchid
// };
//}
)
.CreateLogger(); .CreateLogger();
cfg.ClearProviders() cfg.ClearProviders().AddSerilog(Log.Logger);
.AddSerilog(Log.Logger);
}); });
services services
@@ -155,7 +121,17 @@ public partial class App : Application
base.OnFrameworkInitializationCompleted(); base.OnFrameworkInitializationCompleted();
} }
private static void DisableAvaloniaDataAnnotationValidation()
{
// Get an array of plugins to remove
var dataValidationPluginsToRemove = BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
// remove each entry found
foreach (var plugin in dataValidationPluginsToRemove)
{
BindingPlugins.DataValidators.Remove(plugin);
}
}
private void OnShutdownRequested(object? sender, ShutdownRequestedEventArgs e) private void OnShutdownRequested(object? sender, ShutdownRequestedEventArgs e)
=> CleanUp(); => CleanUp();
@@ -169,23 +145,25 @@ public partial class App : Application
CleanUp(); CleanUp();
} }
private void ShowMessageBox(string title, string message) private static void ShowMessageBox(string title, string message)
{ {
MessageBox.Avalonia.BaseWindows.Base.IMsBoxWindow<ButtonResult> messageBoxStandardWindow = MessageBoxManager var box = MessageBoxManager.GetMessageBoxStandard(
.GetMessageBoxStandardWindow(title, message, ButtonEnum.Ok, Icon.Stop); "Exception",
text: message,
messageBoxStandardWindow.Show(); ButtonEnum.Ok,
Icon.Stop
);
_ = box.ShowAsync().GetAwaiter();
} }
private void LogStartingMode() private void LogStartingMode()
{ {
// Get the Launch mode // Get the Launch mode
bool isDevelopment = string.Equals(Environment.GetEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES"), "debug", bool isDevelopment = string.Equals(Environment.GetEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES"), "debug",
StringComparison.InvariantCultureIgnoreCase); StringComparison.OrdinalIgnoreCase);
// initialize a logger & EventId // initialize a logger & EventId
ILogger<App> logger = _host!.Services.GetRequiredService<ILogger<App>>(); ILogger<App> logger = _host!.Services.GetRequiredService<ILogger<App>>();
EventId eventId = new EventId(id: 0, name: Assembly.GetEntryAssembly()!.GetName().Name); EventId eventId = new(id: 0, name: Assembly.GetEntryAssembly()!.GetName().Name);
// log a test pattern for each log level // log a test pattern for each log level
logger.TestPattern(eventId: eventId); logger.TestPattern(eventId: eventId);
@@ -197,7 +175,7 @@ public partial class App : Application
private void CleanUp() private void CleanUp()
{ {
// tell the background services that we are shutting down // tell the background services that we are shutting down
_ = _host!.StopAsync(_cancellationTokenSource!.Token); _ = _host?.StopAsync(_cancellationTokenSource?.Token ?? CancellationToken.None);
// flush logs // flush logs
Log.CloseAndFlush(); Log.CloseAndFlush();
@@ -4,6 +4,12 @@
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="Assets\avalonia-logo.ico" />
</ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\avalonia-logo.ico" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="appsettings.Development.json"> <Content Include="appsettings.Development.json">
@@ -2,15 +2,24 @@ using Avalonia.Controls;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using AvaloniaSerilogDI.ViewModels; using AvaloniaSerilogDI.ViewModels;
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace AvaloniaSerilogDI; namespace AvaloniaSerilogDI;
// <summary>
/// Given a view model, returns the corresponding view if possible.
/// </summary>
[RequiresUnreferencedCode(
"Default implementation of ViewLocator involves reflection which may be trimmed away.",
Url = "https://docs.avaloniaui.net/docs/concepts/view-locator")]
public class ViewLocator : IDataTemplate public class ViewLocator : IDataTemplate
{ {
public IControl Build(object data) public Control? Build(object? param)
{ {
string name = data.GetType().FullName!.Replace("ViewModel", "View"); if (param is null)
Type? type = Type.GetType(name); return null;
var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);
var type = Type.GetType(name);
if (type != null) if (type != null)
{ {
@@ -20,7 +29,7 @@ public class ViewLocator : IDataTemplate
return new TextBlock { Text = "Not Found: " + name }; return new TextBlock { Text = "Not Found: " + name };
} }
public bool Match(object data) public bool Match(object? data)
{ {
return data is ViewModelBase; return data is ViewModelBase;
} }
@@ -11,7 +11,7 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
Title="C# AVALONIA SeriLog | LogViewer Control Example - Dot Net 7.0" Title="C# AVALONIA SeriLog | LogViewer Control Example - Dot Net 7.0"
Icon="avares://Avalonia.Resources/Assets/avalonia-logo.ico" Icon="/Assets/avalonia-logo.ico"
WindowStartupLocation="CenterScreen" Height="634" Width="600"> WindowStartupLocation="CenterScreen" Height="634" Width="600">
<control:LogViewerControl DataContext="{Binding LogViewer}" /> <control:LogViewerControl DataContext="{Binding LogViewer}" />
@@ -3,7 +3,7 @@
x:Class="AvaloniaSerilogNoDI.App"> x:Class="AvaloniaSerilogNoDI.App">
<Application.Styles> <Application.Styles>
<FluentTheme Mode="Light"/> <FluentTheme/>
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>
@@ -4,6 +4,12 @@
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="Assets\avalonia-logo.ico" />
</ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\avalonia-logo.ico" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="appsettings.Development.json"> <Content Include="appsettings.Development.json">
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
using Serilog; using Serilog;
using Serilog.Sinks.LogView.Core; using Serilog.Sinks.LogView.Core;
using System.Drawing; using System.Drawing;
using System.Globalization;
namespace AvaloniaSerilogNoDI.Helpers; namespace AvaloniaSerilogNoDI.Helpers;
@@ -21,10 +22,7 @@ public static class LoggingHelper
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration) .ReadFrom.Configuration(configuration)
.WriteTo.DataStoreLoggerSink( .WriteTo.DataStoreLoggerSink(dataStoreProvider: () => MainControlsDataStore.DataStore,
//dataStoreProvider: () => MainControlsDataStore.DataStore
dataStoreProvider: () => MainControlsDataStore.DataStore,
options => options =>
{ {
options.Colors[LogLevel.Trace] = new() options.Colors[LogLevel.Trace] = new()
@@ -50,7 +48,7 @@ public static class LoggingHelper
Foreground = Color.White, Foreground = Color.White,
Background = Color.Orchid Background = Color.Orchid
}; };
} }, formatProvider: CultureInfo.InvariantCulture
) )
.CreateLogger(); .CreateLogger();
@@ -11,7 +11,7 @@
xmlns:control="clr-namespace:LogViewer.Avalonia;assembly=LogViewer.Avalonia" xmlns:control="clr-namespace:LogViewer.Avalonia;assembly=LogViewer.Avalonia"
Title="C# AVALONIA | SeriLog LogViewer Control Example - Dot Net 7.0" Title="C# AVALONIA | SeriLog LogViewer Control Example - Dot Net 7.0"
Icon="avares://Avalonia.Resources/Assets/avalonia-logo.ico" Icon="/Assets/avalonia-logo.ico"
WindowStartupLocation="CenterScreen" Height="634" Width="600"> WindowStartupLocation="CenterScreen" Height="634" Width="600">
<control:LogViewerControl x:Name="LogViewerControl" /> <control:LogViewerControl x:Name="LogViewerControl" />
@@ -2,18 +2,20 @@
<PropertyGroup> <PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.13" /> <PackageReference Include="Avalonia" Version="11.3.13" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.13" /> <PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.13" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.13" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.13" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.13" />
<PackageReference Include="Avalonia.Themes.Simple" Version="11.3.13" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.--> <!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.3.13" /> <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.3.13" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
<PackageReference Include="XamlNameReferenceGenerator" Version="1.6.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.5" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.5" />
<PackageReference Include="MessageBox.Avalonia" Version="3.3.1.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -34,7 +34,7 @@
</Style> </Style>
</Grid.Styles> </Grid.Styles>
<DataGrid x:Name="MyDataGrid" <DataGrid x:Name="MyDataGrid"
Items="{Binding DataStore.Entries}" AutoGenerateColumns="False" ItemsSource="{Binding DataStore.Entries}" AutoGenerateColumns="False"
CanUserSortColumns="False" CanUserSortColumns="False"
LayoutUpdated="OnLayoutUpdated"> LayoutUpdated="OnLayoutUpdated">
<DataGrid.Columns> <DataGrid.Columns>
@@ -8,7 +8,10 @@ namespace LogViewer.Avalonia;
public partial class LogViewerControl : UserControl public partial class LogViewerControl : UserControl
{ {
public LogViewerControl() public LogViewerControl()
=> InitializeComponent(); {
InitializeComponent();
}
private ILogDataStoreImpl? vm; private ILogDataStoreImpl? vm;
private LogModel? item; private LogModel? item;
@@ -23,7 +26,7 @@ public partial class LogViewerControl : UserControl
} }
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
=> item = MyDataGrid.Items.Cast<LogModel>().LastOrDefault(); => item = MyDataGrid.ItemsSource.Cast<LogModel>().LastOrDefault();
private void OnLayoutUpdated(object? sender, EventArgs e) private void OnLayoutUpdated(object? sender, EventArgs e)
{ {