initial commit
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Media;
|
||||
using SysDrawColor = System.Drawing.Color;
|
||||
|
||||
namespace LogViewer.Avalonia.Converters;
|
||||
|
||||
public class ChangeColorTypeConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is null)
|
||||
return new SolidColorBrush((Color)(parameter ?? Colors.Black));
|
||||
|
||||
SysDrawColor sysDrawColor = (SysDrawColor)value!;
|
||||
return new SolidColorBrush(Color.FromArgb(
|
||||
sysDrawColor.A,
|
||||
sysDrawColor.R,
|
||||
sysDrawColor.G,
|
||||
sysDrawColor.B));
|
||||
}
|
||||
|
||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
=> throw new NotImplementedException();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LogViewer.Avalonia.Converters;
|
||||
|
||||
public class EventIdConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is null)
|
||||
return "0";
|
||||
|
||||
EventId eventId = (EventId)value;
|
||||
|
||||
return eventId.ToString();
|
||||
}
|
||||
|
||||
// If not implemented, an error is thrown
|
||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
=> new EventId(0, value?.ToString() ?? string.Empty);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using LogViewer.Core;
|
||||
using LogViewer.Core.ViewModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using LogDataStore = LogViewer.Avalonia.Logging.LogDataStore;
|
||||
|
||||
namespace LogViewer.Avalonia;
|
||||
|
||||
public static class ServicesExtension
|
||||
{
|
||||
public static HostApplicationBuilder AddLogViewer(this HostApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton<ILogDataStore, LogDataStore>();
|
||||
builder.Services.AddSingleton<LogViewerControlViewModel>();
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.18" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.18" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.18" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.18" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
|
||||
<PackageReference Include="XamlNameReferenceGenerator" Version="1.6.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Core\LogViewer.Core\LogViewer.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="LogViewerControl.axaml.cs">
|
||||
<DependentUpon>%(Filename)</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,58 @@
|
||||
<UserControl x:Class="LogViewer.Avalonia.LogViewerControl"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
|
||||
xmlns:converters="clr-namespace:LogViewer.Avalonia.Converters"
|
||||
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" DataContextChanged="OnDataContextChanged"
|
||||
DetachedFromLogicalTree="OnDetachedFromLogicalTree">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.Resources>
|
||||
<converters:ChangeColorTypeConverter x:Key="ColorConverter" />
|
||||
<converters:EventIdConverter x:Key="EventIdConverter"/>
|
||||
<SolidColorBrush x:Key="ColorBlack">Black</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="ColorTransparent">Transparent</SolidColorBrush>
|
||||
</Grid.Resources>
|
||||
<Grid.Styles>
|
||||
<Style Selector="DataGridRow">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Foreground" Value="{Binding Color.Foreground,
|
||||
Converter={StaticResource ColorConverter}, ConverterParameter={StaticResource ColorBlack}}" />
|
||||
<Setter Property="Background" Value="{Binding Color.Background,
|
||||
Converter={StaticResource ColorConverter}, ConverterParameter={StaticResource ColorTransparent}}" />
|
||||
</Style>
|
||||
<Style Selector="DataGridCell.size">
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
<DataGrid x:Name="MyDataGrid"
|
||||
Items="{Binding DataStore.Entries}" AutoGenerateColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
LayoutUpdated="OnLayoutUpdated">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn CellStyleClasses="size" Header="Time" Width="150" Binding="{Binding Timestamp}"/>
|
||||
<DataGridTextColumn CellStyleClasses="size" Header="Level" Width="90" Binding="{Binding LogLevel}" />
|
||||
<DataGridTextColumn CellStyleClasses="size" Header="Event Id" Width="120" Binding="{Binding EventId, Converter={StaticResource EventIdConverter}}" />
|
||||
<DataGridTextColumn CellStyleClasses="size" Header="State" Width="300" Binding="{Binding State}" />
|
||||
<DataGridTextColumn CellStyleClasses="size" Header="Exception" Width="300" Binding="{Binding Exception}" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<CheckBox x:Name="CanAutoScroll"
|
||||
FontSize="11"
|
||||
Content="Auto Scroll log"
|
||||
IsChecked="True"
|
||||
Grid.Row="1"
|
||||
Margin="20 10" />
|
||||
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections.Specialized;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.LogicalTree;
|
||||
using LogViewer.Core;
|
||||
|
||||
namespace LogViewer.Avalonia;
|
||||
|
||||
public partial class LogViewerControl : UserControl
|
||||
{
|
||||
public LogViewerControl()
|
||||
=> InitializeComponent();
|
||||
|
||||
private ILogDataStoreImpl? vm;
|
||||
private LogModel? item;
|
||||
|
||||
private void OnDataContextChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (DataContext is null)
|
||||
return;
|
||||
|
||||
vm = (ILogDataStoreImpl)DataContext;
|
||||
vm.DataStore.Entries.CollectionChanged += OnCollectionChanged;
|
||||
}
|
||||
|
||||
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
=> item = MyDataGrid.Items.Cast<LogModel>().LastOrDefault();
|
||||
|
||||
private void OnLayoutUpdated(object? sender, EventArgs e)
|
||||
{
|
||||
if (CanAutoScroll.IsChecked != true || item is null)
|
||||
return;
|
||||
|
||||
MyDataGrid.ScrollIntoView(item, null);
|
||||
item = null;
|
||||
}
|
||||
|
||||
private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
if (vm is null) return;
|
||||
vm.DataStore.Entries.CollectionChanged -= OnCollectionChanged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace LogViewer.Avalonia.Logging;
|
||||
|
||||
public class LogDataStore : Core.LogDataStore
|
||||
{
|
||||
#region Methods
|
||||
|
||||
public override async void AddEntry(Core.LogModel logModel)
|
||||
=> await Dispatcher.UIThread.InvokeAsync(() => base.AddEntry(logModel));
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user