Sicherung
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.31321.278
|
VisualStudioVersion = 17.0.32112.339
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSI.Lib", "FSI.Lib\FSI.Lib.csproj", "{1394B606-4AAC-4D8D-BAF4-DB38E1FCEAAA}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSI.Lib", "FSI.Lib\FSI.Lib.csproj", "{1394B606-4AAC-4D8D-BAF4-DB38E1FCEAAA}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
|
||||||
|
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
|
||||||
<PackageReference Include="TextCopy" Version="6.2.1" />
|
<PackageReference Include="TextCopy" Version="6.2.1" />
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using System;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using NLog;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
@@ -19,11 +22,13 @@ namespace FSI.Lib.Guis.AutoPw
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class FrmMain : Window
|
public partial class FrmMain : Window
|
||||||
{
|
{
|
||||||
|
private Logger _log;
|
||||||
public bool CloseAtLostFocus { get; set; }
|
public bool CloseAtLostFocus { get; set; }
|
||||||
public bool PwOk { get; set; }
|
public bool PwOk { get; set; }
|
||||||
public FrmMain()
|
public FrmMain()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
BtnOk.IsEnabled = false;
|
BtnOk.IsEnabled = false;
|
||||||
Deactivated += FrmMain_Deactivated;
|
Deactivated += FrmMain_Deactivated;
|
||||||
@@ -38,6 +43,8 @@ namespace FSI.Lib.Guis.AutoPw
|
|||||||
|
|
||||||
private void BtnOk_Click(object sender, RoutedEventArgs e)
|
private void BtnOk_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
_log.Info(GetType().Namespace);
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,10 +87,5 @@ namespace FSI.Lib.Guis.AutoPw
|
|||||||
Close();
|
Close();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TbPw_KeyDown_1(object sender, KeyEventArgs e)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,8 +148,6 @@
|
|||||||
<control:FilterDataGrid.InputBindings>
|
<control:FilterDataGrid.InputBindings>
|
||||||
<MouseBinding MouseAction="LeftDoubleClick"
|
<MouseBinding MouseAction="LeftDoubleClick"
|
||||||
Command="{Binding CmdOpen}" />
|
Command="{Binding CmdOpen}" />
|
||||||
<MouseBinding MouseAction="RightDoubleClick"
|
|
||||||
Command="{Binding CmdCopyToClip}" />
|
|
||||||
|
|
||||||
</control:FilterDataGrid.InputBindings>
|
</control:FilterDataGrid.InputBindings>
|
||||||
<control:FilterDataGrid.Columns>
|
<control:FilterDataGrid.Columns>
|
||||||
|
|||||||
@@ -174,6 +174,9 @@ namespace FSI.Lib.Guis.Folder.Mgt
|
|||||||
|
|
||||||
newDatas.Add(newData);
|
newDatas.Add(newData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newDatas = new ObservableCollection<Model>(newDatas.OrderBy(i => i.DescriptionDtl));
|
||||||
|
|
||||||
return newDatas;
|
return newDatas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
FSI.Lib/FSI.Lib/Guis/IbaDirSync/Model.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace FSI.Lib.Guis.IbaDirSync
|
||||||
|
{
|
||||||
|
public interface IInterface
|
||||||
|
{
|
||||||
|
public bool AutoStart { get; set; }
|
||||||
|
public string Source { get; set; }
|
||||||
|
public string Destination { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace FSI.Lib.Guis.IbaDirSync.Model
|
|
||||||
{
|
|
||||||
public class Iba
|
|
||||||
{
|
|
||||||
public string Source { get; set; }
|
|
||||||
public string Destination { get; set; }
|
|
||||||
public bool AutoStart { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +1,31 @@
|
|||||||
using FSI.Lib.Guis.IbaDirSync.Model;
|
using FSI.Lib.MVVM;
|
||||||
using FSI.Lib.MVVM;
|
|
||||||
using RoboSharp;
|
using RoboSharp;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace FSI.Lib.Guis.IbaDirSync.ViewModel
|
namespace FSI.Lib.Guis.IbaDirSync
|
||||||
{
|
{
|
||||||
public class ViewModelIba : ViewModelBase
|
public class ViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
private ICommand _cmdStart;
|
private ICommand _cmdStart;
|
||||||
private ICommand _cmdStop;
|
private ICommand _cmdStop;
|
||||||
|
|
||||||
private Iba _iba;
|
public ViewModel()
|
||||||
|
|
||||||
public ViewModelIba()
|
|
||||||
{
|
|
||||||
Iba = new Model.Iba();
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ViewModelIba(string destination, string source, bool autoStart)
|
|
||||||
{
|
|
||||||
_iba = new Model.Iba()
|
|
||||||
{
|
|
||||||
Destination = destination,
|
|
||||||
Source = source,
|
|
||||||
AutoStart = autoStart,
|
|
||||||
};
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init()
|
|
||||||
{
|
{
|
||||||
_cmdStart = new RelayCommand<object>(ExecuteStart, CanExecuteStart);
|
_cmdStart = new RelayCommand<object>(ExecuteStart, CanExecuteStart);
|
||||||
_cmdStop = new RelayCommand<object>(ExecuteStop, CanExecuteStop);
|
_cmdStop = new RelayCommand<object>(ExecuteStop, CanExecuteStop);
|
||||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
RoboCopy = new RoboSharp.RoboCommand();
|
RoboCopy = new RoboSharp.RoboCommand();
|
||||||
|
}
|
||||||
|
|
||||||
if (_iba.AutoStart)
|
public IInterface Data { get; set; }
|
||||||
|
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
if (Data.AutoStart)
|
||||||
|
{
|
||||||
ExecuteStart(null);
|
ExecuteStart(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Model.Iba Iba
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _iba;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_iba != value & _iba != null)
|
|
||||||
{
|
|
||||||
_iba = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoboCommand RoboCopy { get; set; }
|
public RoboCommand RoboCopy { get; set; }
|
||||||
@@ -93,8 +64,8 @@ namespace FSI.Lib.Guis.IbaDirSync.ViewModel
|
|||||||
|
|
||||||
private void ExecuteStart(object obj)
|
private void ExecuteStart(object obj)
|
||||||
{
|
{
|
||||||
RoboCopy.CopyOptions.Source = Iba.Source;
|
RoboCopy.CopyOptions.Source = Data.Source;
|
||||||
RoboCopy.CopyOptions.Destination = Iba.Destination;
|
RoboCopy.CopyOptions.Destination = Data.Destination;
|
||||||
RoboCopy.CopyOptions.CopySubdirectories = true;
|
RoboCopy.CopyOptions.CopySubdirectories = true;
|
||||||
RoboCopy.CopyOptions.MonitorSourceChangesLimit = 1;
|
RoboCopy.CopyOptions.MonitorSourceChangesLimit = 1;
|
||||||
RoboCopy.StopIfDisposing = true;
|
RoboCopy.StopIfDisposing = true;
|
||||||
@@ -4,13 +4,14 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FSI.Lib.Guis.SetSizePosExWindow.Model
|
namespace FSI.Lib.Guis.SetSizePosExWindow
|
||||||
{
|
{
|
||||||
public class Window
|
public class IInterface
|
||||||
{
|
{
|
||||||
public string Bezeichnung { get; set; }
|
public string Bezeichnung { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string ClassName { get; set; }
|
public string ClassName { get; set; }
|
||||||
|
public bool AutoStart { get; set; }
|
||||||
public int Height { get; set; }
|
public int Height { get; set; }
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
public int X { get; set; }
|
public int X { get; set; }
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using FSI.Lib.Guis.SetSizePosExWindow.Model;
|
using FSI.Lib.MVVM;
|
||||||
using FSI.Lib.MVVM;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@@ -8,9 +7,9 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
|
namespace FSI.Lib.Guis.SetSizePosExWindow
|
||||||
{
|
{
|
||||||
public class ViewModelWindow : ViewModelBase
|
public class ViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||||
@@ -65,39 +64,15 @@ namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
|
|||||||
private BackgroundWorker backgroundWorker;
|
private BackgroundWorker backgroundWorker;
|
||||||
private ICommand _cmdStart;
|
private ICommand _cmdStart;
|
||||||
private ICommand _cmdStop;
|
private ICommand _cmdStop;
|
||||||
private ObservableCollection<Model.Window> _windows;
|
private ObservableCollection<IInterface> _windows;
|
||||||
private int _updateIntervall;
|
private int _updateIntervall;
|
||||||
private bool _autoStart;
|
private bool _autoStart;
|
||||||
private Window _selectedWindow;
|
private IInterface _selectedWindow;
|
||||||
|
|
||||||
public ViewModelWindow()
|
public ViewModel()
|
||||||
{
|
{
|
||||||
_windows = new ObservableCollection<Model.Window>();
|
_windows = new ObservableCollection<IInterface>();
|
||||||
|
|
||||||
Init();
|
|
||||||
|
|
||||||
if (AutoStart)
|
|
||||||
{
|
|
||||||
ExecuteStart(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ViewModelWindow(bool autoStart)
|
|
||||||
{
|
|
||||||
_windows = new ObservableCollection<Model.Window>();
|
|
||||||
|
|
||||||
Init();
|
|
||||||
|
|
||||||
AutoStart = autoStart;
|
|
||||||
|
|
||||||
if (AutoStart)
|
|
||||||
{
|
|
||||||
ExecuteStart(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init()
|
|
||||||
{
|
|
||||||
_cmdStart = new RelayCommand<object>(ExecuteStart, CanExecuteStart);
|
_cmdStart = new RelayCommand<object>(ExecuteStart, CanExecuteStart);
|
||||||
_cmdStop = new RelayCommand<object>(ExecuteStop, CanExecuteStop);
|
_cmdStop = new RelayCommand<object>(ExecuteStop, CanExecuteStop);
|
||||||
|
|
||||||
@@ -110,7 +85,17 @@ namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
|
|||||||
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
|
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<Model.Window> Windows
|
public IInterface Data { get; set; }
|
||||||
|
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
if (Data.AutoStart)
|
||||||
|
{
|
||||||
|
ExecuteStart(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<IInterface> Windows
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -126,7 +111,7 @@ namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Model.Window SelectedWindow
|
public IInterface SelectedWindow
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -232,7 +217,7 @@ namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (Window window in Windows)
|
foreach (IInterface window in Windows)
|
||||||
{
|
{
|
||||||
// Perform a time consuming operation and report progress.
|
// Perform a time consuming operation and report progress.
|
||||||
Thread.Sleep(UpdateIntervall);
|
Thread.Sleep(UpdateIntervall);
|
||||||
@@ -28,7 +28,7 @@ namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt
|
|||||||
|
|
||||||
private void btnStart_Click(object sender, RoutedEventArgs e)
|
private void btnStart_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
//WinCC.Start();
|
// WinCC.Start();
|
||||||
CtrlMgt();
|
CtrlMgt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.Model
|
namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt
|
||||||
{
|
{
|
||||||
public class WinCC
|
public interface IInterface
|
||||||
{
|
{
|
||||||
public bool AutoStart { get; set; }
|
public bool AutoStart { get; set; }
|
||||||
public int UpdateIntervall { get; set; }
|
public int UpdateIntervall { get; set; }
|
||||||
@@ -14,4 +10,5 @@ namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.Model
|
|||||||
public string WindowsClassName { get; set; }
|
public string WindowsClassName { get; set; }
|
||||||
public string ButtonName { get; set; }
|
public string ButtonName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using FSI.Lib.Guis.SieTiaWinCCMsgMgt.Model;
|
using FSI.Lib.MVVM;
|
||||||
using FSI.Lib.MVVM;
|
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -7,9 +6,9 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.ViewModel
|
namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt
|
||||||
{
|
{
|
||||||
public class ViewModelWinCC : MVVM.ViewModelBase
|
public class ViewModel : MVVM.ViewModelBase
|
||||||
{
|
{
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||||
@@ -37,43 +36,14 @@ namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.ViewModel
|
|||||||
const int WM_LBUTTONUP = 0x0202; // message for Mouse up
|
const int WM_LBUTTONUP = 0x0202; // message for Mouse up
|
||||||
|
|
||||||
private CancellationTokenSource tokenSource = null;
|
private CancellationTokenSource tokenSource = null;
|
||||||
private CancellationToken token;
|
|
||||||
private Task task = null;
|
private Task task = null;
|
||||||
|
|
||||||
|
|
||||||
private BackgroundWorker backgroundWorker;
|
private BackgroundWorker backgroundWorker;
|
||||||
private ICommand _cmdStart;
|
private ICommand _cmdStart;
|
||||||
private ICommand _cmdStop;
|
private ICommand _cmdStop;
|
||||||
private WinCC _winCC;
|
|
||||||
|
|
||||||
public ViewModelWinCC()
|
|
||||||
{
|
|
||||||
WinCC = new Model.WinCC();
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ViewModelWinCC(bool autoStart, int updateIntervall, string windowsName, string windowsClassName, string buttonName)
|
public ViewModel()
|
||||||
{
|
|
||||||
_winCC = new Model.WinCC
|
|
||||||
{
|
|
||||||
AutoStart = autoStart,
|
|
||||||
UpdateIntervall = updateIntervall,
|
|
||||||
WindowsName = windowsName,
|
|
||||||
WindowsClassName = windowsClassName,
|
|
||||||
ButtonName = buttonName
|
|
||||||
};
|
|
||||||
|
|
||||||
//_seletctedWinCC = WinCC;
|
|
||||||
|
|
||||||
Init();
|
|
||||||
|
|
||||||
if (WinCC.AutoStart)
|
|
||||||
{
|
|
||||||
ExecuteStart(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init()
|
|
||||||
{
|
{
|
||||||
_cmdStart = new RelayCommand<object>(ExecuteStart, CanExecuteStart);
|
_cmdStart = new RelayCommand<object>(ExecuteStart, CanExecuteStart);
|
||||||
_cmdStop = new RelayCommand<object>(ExecuteStop, CanExecuteStop);
|
_cmdStop = new RelayCommand<object>(ExecuteStop, CanExecuteStop);
|
||||||
@@ -84,22 +54,16 @@ namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.ViewModel
|
|||||||
WorkerSupportsCancellation = true
|
WorkerSupportsCancellation = true
|
||||||
};
|
};
|
||||||
backgroundWorker.DoWork += BackgroundWorker_DoWork;
|
backgroundWorker.DoWork += BackgroundWorker_DoWork;
|
||||||
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
|
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged; ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Model.WinCC WinCC
|
public IInterface Data { get; set; }
|
||||||
|
|
||||||
|
public void Init()
|
||||||
{
|
{
|
||||||
get
|
if (Data.AutoStart)
|
||||||
{
|
{
|
||||||
return _winCC;
|
ExecuteStart(null);
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_winCC != value & _winCC != null)
|
|
||||||
{
|
|
||||||
_winCC = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +93,6 @@ namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.ViewModel
|
|||||||
set => _cmdStop = value;
|
set => _cmdStop = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool CanExecuteStart(object obj)
|
private bool CanExecuteStart(object obj)
|
||||||
{
|
{
|
||||||
return !Status;
|
return !Status;
|
||||||
@@ -163,44 +126,23 @@ namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.ViewModel
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Perform a time consuming operation and report progress.
|
// Perform a time consuming operation and report progress.
|
||||||
Thread.Sleep(WinCC.UpdateIntervall);
|
Thread.Sleep(Data.UpdateIntervall);
|
||||||
|
|
||||||
// Find windos by Name
|
// Find windos by Name
|
||||||
var windowHandle = FindWindow(WinCC.WindowsClassName, WinCC.WindowsName);
|
var windowHandle = FindWindow(Data.WindowsClassName, Data.WindowsName);
|
||||||
|
|
||||||
if (windowHandle != IntPtr.Zero && IsWindowVisible(windowHandle))
|
if (windowHandle != IntPtr.Zero && IsWindowVisible(windowHandle))
|
||||||
{
|
{
|
||||||
SetForegroundWindow(windowHandle);
|
SetForegroundWindow(windowHandle);
|
||||||
var btnHandle = FindWindowEx(windowHandle, IntPtr.Zero, null, WinCC.ButtonName);
|
var btnHandle = FindWindowEx(windowHandle, IntPtr.Zero, null, Data.ButtonName);
|
||||||
SendMessage(btnHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
|
SendMessage(btnHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool Status { get; set; }
|
public bool Status { get; set; }
|
||||||
|
|
||||||
private void WinCCMsgMgt()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (token.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
token.ThrowIfCancellationRequested();
|
|
||||||
}
|
|
||||||
//MessageBox.Show("13456");
|
|
||||||
Thread.Sleep(5000);
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
bool disposedValue = false;
|
bool disposedValue = false;
|
||||||
@@ -229,6 +171,5 @@ namespace FSI.Lib.Guis.SieTiaWinCCMsgMgt.ViewModel
|
|||||||
task = null;
|
task = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FSI.Lib.Guis.TxtToClip.Mgt
|
namespace FSI.Lib.Guis.TxtToClip.Mgt
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -143,6 +143,8 @@ namespace FSI.Lib.Guis.TxtToClip.Mgt
|
|||||||
|
|
||||||
newDatas.Add(newData);
|
newDatas.Add(newData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newDatas = new ObservableCollection<Model>(newDatas.OrderBy(i => i.DescriptionDtl));
|
||||||
return newDatas;
|
return newDatas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
42
FSI.Lib/NLogViewer/ActionCommand.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace DJ
|
||||||
|
{
|
||||||
|
public sealed class ActionCommand : ICommand
|
||||||
|
{
|
||||||
|
private readonly Action _Action;
|
||||||
|
private readonly Action<object> _ObjectAction;
|
||||||
|
|
||||||
|
public ActionCommand(Action action)
|
||||||
|
{
|
||||||
|
_Action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionCommand(Action<object> objectAction)
|
||||||
|
{
|
||||||
|
_ObjectAction = objectAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
private event EventHandler CanExecuteChanged;
|
||||||
|
|
||||||
|
event EventHandler ICommand.CanExecuteChanged
|
||||||
|
{
|
||||||
|
add => CanExecuteChanged += value;
|
||||||
|
remove => CanExecuteChanged -= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ICommand.CanExecute(object parameter)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(object parameter)
|
||||||
|
{
|
||||||
|
if (_ObjectAction != null)
|
||||||
|
_ObjectAction(parameter);
|
||||||
|
else
|
||||||
|
_Action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
72
FSI.Lib/NLogViewer/Extensions/DependencyObjectExtensions.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace DJ.Extensions
|
||||||
|
{
|
||||||
|
public static class DependencyObjectExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Analyzes both visual and logical tree in order to find all elements of a given
|
||||||
|
/// type that are descendants of the <paramref name="source"/> item.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the queried items.</typeparam>
|
||||||
|
/// <param name="source">The root element that marks the source of the search. If the
|
||||||
|
/// source is already of the requested type, it will not be included in the result.</param>
|
||||||
|
/// <param name="uid">The UID of the <see cref="UIElement"/></param>
|
||||||
|
/// <returns>All descendants of <paramref name="source"/> that match the requested type.</returns>
|
||||||
|
public static T FindChildByUid<T>(this DependencyObject source, string uid) where T : UIElement
|
||||||
|
{
|
||||||
|
if (source != null)
|
||||||
|
{
|
||||||
|
var childs = GetChildObjects(source);
|
||||||
|
foreach (DependencyObject child in childs)
|
||||||
|
{
|
||||||
|
//analyze if children match the requested type
|
||||||
|
if (child != null && child is T dependencyObject && dependencyObject.Uid.Equals(uid))
|
||||||
|
{
|
||||||
|
return dependencyObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
var descendant = FindChildByUid<T>(child, uid);
|
||||||
|
if (descendant != null)
|
||||||
|
return descendant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method is an alternative to WPF's
|
||||||
|
/// <see cref="VisualTreeHelper.GetChild"/> method, which also
|
||||||
|
/// supports content elements. Keep in mind that for content elements,
|
||||||
|
/// this method falls back to the logical tree of the element.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">The item to be processed.</param>
|
||||||
|
/// <returns>The submitted item's child elements, if available.</returns>
|
||||||
|
public static IEnumerable<DependencyObject> GetChildObjects(this DependencyObject parent)
|
||||||
|
{
|
||||||
|
if (parent == null) yield break;
|
||||||
|
|
||||||
|
if (parent is ContentElement || parent is FrameworkElement)
|
||||||
|
{
|
||||||
|
//use the logical tree for content / framework elements
|
||||||
|
foreach (object obj in LogicalTreeHelper.GetChildren(parent))
|
||||||
|
{
|
||||||
|
var depObj = obj as DependencyObject;
|
||||||
|
if (depObj != null) yield return (DependencyObject) obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//use the visual tree per default
|
||||||
|
int count = VisualTreeHelper.GetChildrenCount(parent);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
yield return VisualTreeHelper.GetChild(parent, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
FSI.Lib/NLogViewer/Helper/AutoSizedGridView.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ.Helper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a view mode that displays data items in columns for a System.Windows.Controls.ListView control with auto sized columns based on the column content
|
||||||
|
/// Used to fix the column width: https://stackoverflow.com/questions/60147905/column-width-adjustment-is-broken-if-using-multibinding-on-displaymemberbinding
|
||||||
|
/// </summary>
|
||||||
|
public class AutoSizedGridView : GridView
|
||||||
|
{
|
||||||
|
private int _MaxLoggerNameLength;
|
||||||
|
|
||||||
|
protected override void PrepareItem(ListViewItem item)
|
||||||
|
{
|
||||||
|
if (item.DataContext is LogEventInfo info)
|
||||||
|
{
|
||||||
|
if (info.LoggerName.Length > _MaxLoggerNameLength)
|
||||||
|
{
|
||||||
|
_MaxLoggerNameLength = info.LoggerName.Length;
|
||||||
|
Observable.Timer(TimeSpan.FromMilliseconds(1)).ObserveOn(SynchronizationContext.Current).Subscribe(l =>
|
||||||
|
{
|
||||||
|
foreach (GridViewColumn column in Columns)
|
||||||
|
{
|
||||||
|
//setting NaN for the column width automatically determines the required width enough to hold the content completely.
|
||||||
|
//if column width was set to NaN already, set it ActualWidth temporarily and set to NaN. This raises the property change event and re computes the width.
|
||||||
|
if (double.IsNaN(column.Width))
|
||||||
|
{
|
||||||
|
column.Width = column.ActualWidth;
|
||||||
|
column.Width = double.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.PrepareItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace DJ.Helper.ListViewLayoutManager
|
||||||
|
{
|
||||||
|
public abstract class ConverterGridViewColumn : GridViewColumn, IValueConverter
|
||||||
|
{
|
||||||
|
public Type BindingType => _BindingType;
|
||||||
|
private readonly Type _BindingType;
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Constructor
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
protected ConverterGridViewColumn(Type bindingType)
|
||||||
|
{
|
||||||
|
if (bindingType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(bindingType));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._BindingType = bindingType;
|
||||||
|
|
||||||
|
Binding binding = new Binding {Mode = BindingMode.OneWay, Converter = this};
|
||||||
|
DisplayMemberBinding = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// IValueConverter
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region IValueConverter
|
||||||
|
|
||||||
|
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (!_BindingType.IsInstanceOfType(value))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConvertValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract object ConvertValue(object value);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace DJ.Helper.ListViewLayoutManager
|
||||||
|
{
|
||||||
|
public sealed class FixedColumn : LayoutColumn
|
||||||
|
{
|
||||||
|
public static bool IsFixedColumn(GridViewColumn column)
|
||||||
|
{
|
||||||
|
if (column == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HasPropertyValue(column, WidthProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double? GetFixedWidth(GridViewColumn column)
|
||||||
|
{
|
||||||
|
return GetColumnWidth(column, WidthProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridViewColumn ApplyWidth(GridViewColumn gridViewColumn, double width)
|
||||||
|
{
|
||||||
|
SetWidth(gridViewColumn, width);
|
||||||
|
return gridViewColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// AttachedProperties
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region AttachedProperties
|
||||||
|
|
||||||
|
public static double GetWidth(DependencyObject obj)
|
||||||
|
{
|
||||||
|
return (double) obj.GetValue(WidthProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetWidth(DependencyObject obj, double width)
|
||||||
|
{
|
||||||
|
obj.SetValue(WidthProperty, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty WidthProperty = DependencyProperty.RegisterAttached("Width", typeof(double), typeof(FixedColumn));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Constructor
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
private FixedColumn()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace DJ.Helper.ListViewLayoutManager
|
||||||
|
{
|
||||||
|
public abstract class ImageGridViewColumn : GridViewColumn, IValueConverter
|
||||||
|
{
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Constructor
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
protected ImageGridViewColumn(Stretch imageStretch)
|
||||||
|
{
|
||||||
|
FrameworkElementFactory imageElement = new FrameworkElementFactory(typeof(Image));
|
||||||
|
|
||||||
|
Binding imageSourceBinding = new Binding {Converter = this, Mode = BindingMode.OneWay};
|
||||||
|
imageElement.SetBinding(Image.SourceProperty, imageSourceBinding);
|
||||||
|
|
||||||
|
Binding imageStretchBinding = new Binding {Source = imageStretch};
|
||||||
|
imageElement.SetBinding(Image.StretchProperty, imageStretchBinding);
|
||||||
|
|
||||||
|
DataTemplate template = new DataTemplate {VisualTree = imageElement};
|
||||||
|
CellTemplate = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ImageGridViewColumn() : this(Stretch.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// IValueConverter
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region IValueConverter
|
||||||
|
|
||||||
|
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return GetImageSource(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract ImageSource GetImageSource(object value);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace DJ.Helper.ListViewLayoutManager
|
||||||
|
{
|
||||||
|
public abstract class LayoutColumn
|
||||||
|
{
|
||||||
|
protected static bool HasPropertyValue(GridViewColumn column, DependencyProperty dp)
|
||||||
|
{
|
||||||
|
if (column == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
object value = column.ReadLocalValue(dp);
|
||||||
|
if (value?.GetType() == dp.PropertyType)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static double? GetColumnWidth(GridViewColumn column, DependencyProperty dp)
|
||||||
|
{
|
||||||
|
if (column == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
object value = column.ReadLocalValue(dp);
|
||||||
|
if (value?.GetType() == dp.PropertyType)
|
||||||
|
{
|
||||||
|
return (double) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,623 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace DJ.Helper.ListViewLayoutManager
|
||||||
|
{
|
||||||
|
public class ListViewLayoutManager
|
||||||
|
{
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Properties
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Public Properties
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
public ListView ListView => _ListView;
|
||||||
|
|
||||||
|
public ScrollBarVisibility VerticalScrollBarVisibility
|
||||||
|
{
|
||||||
|
get => _VerticalScrollBarVisibility;
|
||||||
|
set => _VerticalScrollBarVisibility = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Private Properties
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
private readonly ListView _ListView;
|
||||||
|
private ScrollViewer _ScrollViewer;
|
||||||
|
private bool _Loaded;
|
||||||
|
private bool _Resizing;
|
||||||
|
private Cursor _ResizeCursor;
|
||||||
|
private ScrollBarVisibility _VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
|
||||||
|
private GridViewColumn _AutoSizedColumn;
|
||||||
|
|
||||||
|
private const double _ZERO_WIDTH_RANGE = 0.1;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// AttachedProperties
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region AttachedProperties
|
||||||
|
|
||||||
|
public static void SetEnabled(DependencyObject dependencyObject, bool enabled)
|
||||||
|
{
|
||||||
|
dependencyObject.SetValue(EnabledProperty, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty EnabledProperty = DependencyProperty.RegisterAttached("Enabled",
|
||||||
|
typeof(bool), typeof(ListViewLayoutManager), new FrameworkPropertyMetadata(_OnLayoutManagerEnabledChanged));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Constructor
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public ListViewLayoutManager(ListView listView)
|
||||||
|
{
|
||||||
|
_ListView = listView ?? throw new ArgumentNullException(nameof(listView));
|
||||||
|
_ListView.Loaded += ListView_Loaded;
|
||||||
|
_ListView.Unloaded += ListView_Unloaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ListView_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_RegisterEvents(_ListView);
|
||||||
|
_InitColumns();
|
||||||
|
_DoResizeColumns();
|
||||||
|
_Loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ListView_Unloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_Loaded)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_UnRegisterEvents(_ListView);
|
||||||
|
_Loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// public methods
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region public methods
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
_InitColumns();
|
||||||
|
_DoResizeColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void ResizeColumns()
|
||||||
|
{
|
||||||
|
GridView view = _ListView.View as GridView;
|
||||||
|
if (view == null || view.Columns.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// listview width
|
||||||
|
double actualWidth = double.PositiveInfinity;
|
||||||
|
if (_ScrollViewer != null)
|
||||||
|
{
|
||||||
|
actualWidth = _ScrollViewer.ViewportWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (double.IsInfinity(actualWidth))
|
||||||
|
{
|
||||||
|
actualWidth = _ListView.ActualWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (double.IsInfinity(actualWidth) || actualWidth <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double resizeableRegionCount = 0;
|
||||||
|
double otherColumnsWidth = 0;
|
||||||
|
// determine column sizes
|
||||||
|
foreach (GridViewColumn gridViewColumn in view.Columns)
|
||||||
|
{
|
||||||
|
if (ProportionalColumn.IsProportionalColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
double? proportionalWidth = ProportionalColumn.GetProportionalWidth(gridViewColumn);
|
||||||
|
if (proportionalWidth != null)
|
||||||
|
{
|
||||||
|
resizeableRegionCount += proportionalWidth.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
otherColumnsWidth += gridViewColumn.ActualWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resizeableRegionCount <= 0)
|
||||||
|
{
|
||||||
|
// no proportional columns present: commit the regulation to the scroll viewer
|
||||||
|
if (_ScrollViewer != null)
|
||||||
|
{
|
||||||
|
_ScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// search the first fill column
|
||||||
|
GridViewColumn fillColumn = null;
|
||||||
|
for (int i = 0; i < view.Columns.Count; i++)
|
||||||
|
{
|
||||||
|
GridViewColumn gridViewColumn = view.Columns[i];
|
||||||
|
if (_IsFillColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
fillColumn = gridViewColumn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fillColumn != null)
|
||||||
|
{
|
||||||
|
double otherColumnsWithoutFillWidth = otherColumnsWidth - fillColumn.ActualWidth;
|
||||||
|
double fillWidth = actualWidth - otherColumnsWithoutFillWidth;
|
||||||
|
if (fillWidth > 0)
|
||||||
|
{
|
||||||
|
double? minWidth = RangeColumn.GetRangeMinWidth(fillColumn);
|
||||||
|
double? maxWidth = RangeColumn.GetRangeMaxWidth(fillColumn);
|
||||||
|
|
||||||
|
bool setWidth = !(minWidth.HasValue && fillWidth < minWidth.Value);
|
||||||
|
if (maxWidth.HasValue && fillWidth > maxWidth.Value)
|
||||||
|
{
|
||||||
|
setWidth = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setWidth)
|
||||||
|
{
|
||||||
|
if (_ScrollViewer != null)
|
||||||
|
{
|
||||||
|
_ScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
fillColumn.Width = fillWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double resizeableColumnsWidth = actualWidth - otherColumnsWidth;
|
||||||
|
if (resizeableColumnsWidth <= 0)
|
||||||
|
{
|
||||||
|
return; // missing space
|
||||||
|
}
|
||||||
|
|
||||||
|
// resize columns
|
||||||
|
double resizeableRegionWidth = resizeableColumnsWidth / resizeableRegionCount;
|
||||||
|
foreach (GridViewColumn gridViewColumn in view.Columns)
|
||||||
|
{
|
||||||
|
if (ProportionalColumn.IsProportionalColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
double? proportionalWidth = ProportionalColumn.GetProportionalWidth(gridViewColumn);
|
||||||
|
if (proportionalWidth != null)
|
||||||
|
{
|
||||||
|
gridViewColumn.Width = proportionalWidth.Value * resizeableRegionWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// private methods
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region private methods
|
||||||
|
|
||||||
|
private void _DoResizeColumns()
|
||||||
|
{
|
||||||
|
if (_Resizing)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Resizing = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ResizeColumns();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_Resizing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _RegisterEvents(DependencyObject start)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(start); i++)
|
||||||
|
{
|
||||||
|
Visual childVisual = VisualTreeHelper.GetChild(start, i) as Visual;
|
||||||
|
if (childVisual is Thumb)
|
||||||
|
{
|
||||||
|
GridViewColumn gridViewColumn = _FindParentColumn(childVisual);
|
||||||
|
if (gridViewColumn != null)
|
||||||
|
{
|
||||||
|
Thumb thumb = childVisual as Thumb;
|
||||||
|
if (ProportionalColumn.IsProportionalColumn(gridViewColumn) ||
|
||||||
|
FixedColumn.IsFixedColumn(gridViewColumn) || _IsFillColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
thumb.IsHitTestVisible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thumb.PreviewMouseMove += _ThumbPreviewMouseMove;
|
||||||
|
thumb.PreviewMouseLeftButtonDown +=
|
||||||
|
_ThumbPreviewMouseLeftButtonDown;
|
||||||
|
DependencyPropertyDescriptor.FromProperty(
|
||||||
|
GridViewColumn.WidthProperty,
|
||||||
|
typeof(GridViewColumn)).AddValueChanged(gridViewColumn, _GridColumnWidthChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (childVisual is GridViewColumnHeader)
|
||||||
|
{
|
||||||
|
GridViewColumnHeader columnHeader = childVisual as GridViewColumnHeader;
|
||||||
|
columnHeader.SizeChanged += _GridColumnHeaderSizeChanged;
|
||||||
|
}
|
||||||
|
else if (_ScrollViewer == null && childVisual is ScrollViewer)
|
||||||
|
{
|
||||||
|
_ScrollViewer = childVisual as ScrollViewer;
|
||||||
|
_ScrollViewer.ScrollChanged += _ScrollViewerScrollChanged;
|
||||||
|
// assume we do the regulation of the horizontal scrollbar
|
||||||
|
_ScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
|
||||||
|
_ScrollViewer.VerticalScrollBarVisibility = _VerticalScrollBarVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
_RegisterEvents(childVisual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _UnRegisterEvents(DependencyObject start)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(start); i++)
|
||||||
|
{
|
||||||
|
Visual childVisual = VisualTreeHelper.GetChild(start, i) as Visual;
|
||||||
|
if (childVisual is Thumb)
|
||||||
|
{
|
||||||
|
GridViewColumn gridViewColumn = _FindParentColumn(childVisual);
|
||||||
|
if (gridViewColumn != null)
|
||||||
|
{
|
||||||
|
Thumb thumb = childVisual as Thumb;
|
||||||
|
if (ProportionalColumn.IsProportionalColumn(gridViewColumn) ||
|
||||||
|
FixedColumn.IsFixedColumn(gridViewColumn) || _IsFillColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
thumb.IsHitTestVisible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thumb.PreviewMouseMove -= _ThumbPreviewMouseMove;
|
||||||
|
thumb.PreviewMouseLeftButtonDown -=
|
||||||
|
_ThumbPreviewMouseLeftButtonDown;
|
||||||
|
DependencyPropertyDescriptor.FromProperty(
|
||||||
|
GridViewColumn.WidthProperty,
|
||||||
|
typeof(GridViewColumn)).RemoveValueChanged(gridViewColumn, _GridColumnWidthChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (childVisual is GridViewColumnHeader)
|
||||||
|
{
|
||||||
|
GridViewColumnHeader columnHeader = childVisual as GridViewColumnHeader;
|
||||||
|
columnHeader.SizeChanged -= _GridColumnHeaderSizeChanged;
|
||||||
|
}
|
||||||
|
else if (_ScrollViewer == null && childVisual is ScrollViewer)
|
||||||
|
{
|
||||||
|
_ScrollViewer = childVisual as ScrollViewer;
|
||||||
|
_ScrollViewer.ScrollChanged -= _ScrollViewerScrollChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
_UnRegisterEvents(childVisual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridViewColumn _FindParentColumn(DependencyObject element)
|
||||||
|
{
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (element != null)
|
||||||
|
{
|
||||||
|
GridViewColumnHeader gridViewColumnHeader = element as GridViewColumnHeader;
|
||||||
|
if (gridViewColumnHeader != null)
|
||||||
|
{
|
||||||
|
return (gridViewColumnHeader).Column;
|
||||||
|
}
|
||||||
|
|
||||||
|
element = VisualTreeHelper.GetParent(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridViewColumnHeader _FindColumnHeader(DependencyObject start, GridViewColumn gridViewColumn)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(start); i++)
|
||||||
|
{
|
||||||
|
Visual childVisual = VisualTreeHelper.GetChild(start, i) as Visual;
|
||||||
|
if (childVisual is GridViewColumnHeader)
|
||||||
|
{
|
||||||
|
GridViewColumnHeader gridViewHeader = childVisual as GridViewColumnHeader;
|
||||||
|
if (gridViewHeader.Column == gridViewColumn)
|
||||||
|
{
|
||||||
|
return gridViewHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridViewColumnHeader childGridViewHeader = _FindColumnHeader(childVisual, gridViewColumn);
|
||||||
|
if (childGridViewHeader != null)
|
||||||
|
{
|
||||||
|
return childGridViewHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _InitColumns()
|
||||||
|
{
|
||||||
|
GridView view = _ListView.View as GridView;
|
||||||
|
if (view == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (GridViewColumn gridViewColumn in view.Columns)
|
||||||
|
{
|
||||||
|
if (!RangeColumn.IsRangeColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double? minWidth = RangeColumn.GetRangeMinWidth(gridViewColumn);
|
||||||
|
double? maxWidth = RangeColumn.GetRangeMaxWidth(gridViewColumn);
|
||||||
|
if (!minWidth.HasValue && !maxWidth.HasValue)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridViewColumnHeader columnHeader = _FindColumnHeader(_ListView, gridViewColumn);
|
||||||
|
if (columnHeader == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double actualWidth = columnHeader.ActualWidth;
|
||||||
|
if (minWidth.HasValue)
|
||||||
|
{
|
||||||
|
columnHeader.MinWidth = minWidth.Value;
|
||||||
|
if (!double.IsInfinity(actualWidth) && actualWidth < columnHeader.MinWidth)
|
||||||
|
{
|
||||||
|
gridViewColumn.Width = columnHeader.MinWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxWidth.HasValue)
|
||||||
|
{
|
||||||
|
columnHeader.MaxWidth = maxWidth.Value;
|
||||||
|
if (!double.IsInfinity(actualWidth) && actualWidth > columnHeader.MaxWidth)
|
||||||
|
{
|
||||||
|
gridViewColumn.Width = columnHeader.MaxWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the delta
|
||||||
|
private double _SetRangeColumnToBounds(GridViewColumn gridViewColumn)
|
||||||
|
{
|
||||||
|
double startWidth = gridViewColumn.Width;
|
||||||
|
|
||||||
|
double? minWidth = RangeColumn.GetRangeMinWidth(gridViewColumn);
|
||||||
|
double? maxWidth = RangeColumn.GetRangeMaxWidth(gridViewColumn);
|
||||||
|
|
||||||
|
if ((minWidth.HasValue && maxWidth.HasValue) && (minWidth > maxWidth))
|
||||||
|
{
|
||||||
|
return 0; // invalid case
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minWidth.HasValue && gridViewColumn.Width < minWidth.Value)
|
||||||
|
{
|
||||||
|
gridViewColumn.Width = minWidth.Value;
|
||||||
|
}
|
||||||
|
else if (maxWidth.HasValue && gridViewColumn.Width > maxWidth.Value)
|
||||||
|
{
|
||||||
|
gridViewColumn.Width = maxWidth.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gridViewColumn.Width - startWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _IsFillColumn(GridViewColumn gridViewColumn)
|
||||||
|
{
|
||||||
|
if (gridViewColumn == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView view = _ListView.View as GridView;
|
||||||
|
if (view == null || view.Columns.Count == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? isFillColumn = RangeColumn.GetRangeIsFillColumn(gridViewColumn);
|
||||||
|
return isFillColumn.HasValue && isFillColumn.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ThumbPreviewMouseMove(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
Thumb thumb = sender as Thumb;
|
||||||
|
if (thumb == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridViewColumn gridViewColumn = _FindParentColumn(thumb);
|
||||||
|
if (gridViewColumn == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// suppress column resizing for proportional, fixed and range fill columns
|
||||||
|
if (ProportionalColumn.IsProportionalColumn(gridViewColumn) ||
|
||||||
|
FixedColumn.IsFixedColumn(gridViewColumn) ||
|
||||||
|
_IsFillColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
thumb.Cursor = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check range column bounds
|
||||||
|
if (thumb.IsMouseCaptured && RangeColumn.IsRangeColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
double? minWidth = RangeColumn.GetRangeMinWidth(gridViewColumn);
|
||||||
|
double? maxWidth = RangeColumn.GetRangeMaxWidth(gridViewColumn);
|
||||||
|
|
||||||
|
if ((minWidth.HasValue && maxWidth.HasValue) && (minWidth > maxWidth))
|
||||||
|
{
|
||||||
|
return; // invalid case
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ResizeCursor == null)
|
||||||
|
{
|
||||||
|
_ResizeCursor = thumb.Cursor; // save the resize cursor
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minWidth.HasValue && gridViewColumn.Width <= minWidth.Value)
|
||||||
|
{
|
||||||
|
thumb.Cursor = Cursors.No;
|
||||||
|
}
|
||||||
|
else if (maxWidth.HasValue && gridViewColumn.Width >= maxWidth.Value)
|
||||||
|
{
|
||||||
|
thumb.Cursor = Cursors.No;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thumb.Cursor = _ResizeCursor; // between valid min/max
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ThumbPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
Thumb thumb = sender as Thumb;
|
||||||
|
GridViewColumn gridViewColumn = _FindParentColumn(thumb);
|
||||||
|
|
||||||
|
// suppress column resizing for proportional, fixed and range fill columns
|
||||||
|
if (ProportionalColumn.IsProportionalColumn(gridViewColumn) ||
|
||||||
|
FixedColumn.IsFixedColumn(gridViewColumn) ||
|
||||||
|
_IsFillColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _GridColumnWidthChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!_Loaded)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridViewColumn gridViewColumn = sender as GridViewColumn;
|
||||||
|
|
||||||
|
// suppress column resizing for proportional and fixed columns
|
||||||
|
if (ProportionalColumn.IsProportionalColumn(gridViewColumn) || FixedColumn.IsFixedColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure range column within the bounds
|
||||||
|
if (RangeColumn.IsRangeColumn(gridViewColumn))
|
||||||
|
{
|
||||||
|
// special case: auto column width - maybe conflicts with min/max range
|
||||||
|
if (gridViewColumn != null && gridViewColumn.Width.Equals(double.NaN))
|
||||||
|
{
|
||||||
|
_AutoSizedColumn = gridViewColumn;
|
||||||
|
return; // handled by the change header size event
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure column bounds
|
||||||
|
if (Math.Abs(_SetRangeColumnToBounds(gridViewColumn) - 0) > _ZERO_WIDTH_RANGE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_DoResizeColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle autosized column
|
||||||
|
private void _GridColumnHeaderSizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_AutoSizedColumn == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridViewColumnHeader gridViewColumnHeader = sender as GridViewColumnHeader;
|
||||||
|
if (gridViewColumnHeader != null && gridViewColumnHeader.Column == _AutoSizedColumn)
|
||||||
|
{
|
||||||
|
if (gridViewColumnHeader.Width.Equals(double.NaN))
|
||||||
|
{
|
||||||
|
// sync column with
|
||||||
|
gridViewColumnHeader.Column.Width = gridViewColumnHeader.ActualWidth;
|
||||||
|
_DoResizeColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
_AutoSizedColumn = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_Loaded && Math.Abs(e.ViewportWidthChange - 0) > _ZERO_WIDTH_RANGE)
|
||||||
|
{
|
||||||
|
_DoResizeColumns();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _OnLayoutManagerEnabledChanged(DependencyObject dependencyObject,
|
||||||
|
DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
ListView listView = dependencyObject as ListView;
|
||||||
|
if (listView != null)
|
||||||
|
{
|
||||||
|
bool enabled = (bool) e.NewValue;
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
new ListViewLayoutManager(listView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace DJ.Helper.ListViewLayoutManager
|
||||||
|
{
|
||||||
|
public sealed class ProportionalColumn : LayoutColumn
|
||||||
|
{
|
||||||
|
public static bool IsProportionalColumn(GridViewColumn column)
|
||||||
|
{
|
||||||
|
if (column == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HasPropertyValue(column, WidthProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double? GetProportionalWidth(GridViewColumn column)
|
||||||
|
{
|
||||||
|
return GetColumnWidth(column, WidthProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridViewColumn ApplyWidth(GridViewColumn gridViewColumn, double width)
|
||||||
|
{
|
||||||
|
SetWidth(gridViewColumn, width);
|
||||||
|
return gridViewColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// AttachedProperties
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region AttachedProperties
|
||||||
|
|
||||||
|
public static double GetWidth(DependencyObject obj)
|
||||||
|
{
|
||||||
|
return (double) obj.GetValue(WidthProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetWidth(DependencyObject obj, double width)
|
||||||
|
{
|
||||||
|
obj.SetValue(WidthProperty, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty WidthProperty = DependencyProperty.RegisterAttached("Width", typeof(double), typeof(ProportionalColumn));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Constructor
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
private ProportionalColumn()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
136
FSI.Lib/NLogViewer/Helper/ListViewLayoutManager/RangeColumn.cs
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace DJ.Helper.ListViewLayoutManager
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class RangeColumn : LayoutColumn
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly DependencyProperty MinWidthProperty =
|
||||||
|
DependencyProperty.RegisterAttached(
|
||||||
|
"MinWidth",
|
||||||
|
typeof( double ),
|
||||||
|
typeof( RangeColumn ) );
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly DependencyProperty MaxWidthProperty =
|
||||||
|
DependencyProperty.RegisterAttached(
|
||||||
|
"MaxWidth",
|
||||||
|
typeof( double ),
|
||||||
|
typeof( RangeColumn ) );
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IsFillColumnProperty =
|
||||||
|
DependencyProperty.RegisterAttached(
|
||||||
|
"IsFillColumn",
|
||||||
|
typeof( bool ),
|
||||||
|
typeof( RangeColumn ) );
|
||||||
|
|
||||||
|
|
||||||
|
private RangeColumn()
|
||||||
|
{
|
||||||
|
} // RangeColumn
|
||||||
|
|
||||||
|
|
||||||
|
public static double GetMinWidth( DependencyObject obj )
|
||||||
|
{
|
||||||
|
return (double)obj.GetValue( MinWidthProperty );
|
||||||
|
} // GetMinWidth
|
||||||
|
|
||||||
|
|
||||||
|
public static void SetMinWidth( DependencyObject obj, double minWidth )
|
||||||
|
{
|
||||||
|
obj.SetValue( MinWidthProperty, minWidth );
|
||||||
|
} // SetMinWidth
|
||||||
|
|
||||||
|
|
||||||
|
public static double GetMaxWidth( DependencyObject obj )
|
||||||
|
{
|
||||||
|
return (double)obj.GetValue( MaxWidthProperty );
|
||||||
|
} // GetMaxWidth
|
||||||
|
|
||||||
|
|
||||||
|
public static void SetMaxWidth( DependencyObject obj, double maxWidth )
|
||||||
|
{
|
||||||
|
obj.SetValue( MaxWidthProperty, maxWidth );
|
||||||
|
} // SetMaxWidth
|
||||||
|
|
||||||
|
|
||||||
|
public static bool GetIsFillColumn( DependencyObject obj )
|
||||||
|
{
|
||||||
|
return (bool)obj.GetValue( IsFillColumnProperty );
|
||||||
|
} // GetIsFillColumn
|
||||||
|
|
||||||
|
|
||||||
|
public static void SetIsFillColumn( DependencyObject obj, bool isFillColumn )
|
||||||
|
{
|
||||||
|
obj.SetValue( IsFillColumnProperty, isFillColumn );
|
||||||
|
} // SetIsFillColumn
|
||||||
|
|
||||||
|
|
||||||
|
public static bool IsRangeColumn( GridViewColumn column )
|
||||||
|
{
|
||||||
|
if ( column == null )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return
|
||||||
|
HasPropertyValue( column, MinWidthProperty ) ||
|
||||||
|
HasPropertyValue( column, MaxWidthProperty ) ||
|
||||||
|
HasPropertyValue( column, IsFillColumnProperty );
|
||||||
|
} // IsRangeColumn
|
||||||
|
|
||||||
|
|
||||||
|
public static double? GetRangeMinWidth( GridViewColumn column )
|
||||||
|
{
|
||||||
|
return GetColumnWidth( column, MinWidthProperty );
|
||||||
|
} // GetRangeMinWidth
|
||||||
|
|
||||||
|
|
||||||
|
public static double? GetRangeMaxWidth( GridViewColumn column )
|
||||||
|
{
|
||||||
|
return GetColumnWidth( column, MaxWidthProperty );
|
||||||
|
} // GetRangeMaxWidth
|
||||||
|
|
||||||
|
|
||||||
|
public static bool? GetRangeIsFillColumn( GridViewColumn column )
|
||||||
|
{
|
||||||
|
if ( column == null )
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException( nameof(column) );
|
||||||
|
}
|
||||||
|
object value = column.ReadLocalValue( IsFillColumnProperty );
|
||||||
|
if ( value != null && value.GetType() == IsFillColumnProperty.PropertyType )
|
||||||
|
{
|
||||||
|
return (bool)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} // GetRangeIsFillColumn
|
||||||
|
|
||||||
|
|
||||||
|
public static GridViewColumn ApplyWidth( GridViewColumn gridViewColumn, double minWidth,
|
||||||
|
double width, double maxWidth )
|
||||||
|
{
|
||||||
|
return ApplyWidth( gridViewColumn, minWidth, width, maxWidth, false );
|
||||||
|
} // ApplyWidth
|
||||||
|
|
||||||
|
|
||||||
|
public static GridViewColumn ApplyWidth( GridViewColumn gridViewColumn, double minWidth,
|
||||||
|
double width, double maxWidth, bool isFillColumn )
|
||||||
|
{
|
||||||
|
SetMinWidth( gridViewColumn, minWidth );
|
||||||
|
gridViewColumn.Width = width;
|
||||||
|
SetMaxWidth( gridViewColumn, maxWidth );
|
||||||
|
SetIsFillColumn( gridViewColumn, isFillColumn );
|
||||||
|
return gridViewColumn;
|
||||||
|
} // ApplyWidth
|
||||||
|
|
||||||
|
} // class RangeColumn
|
||||||
|
|
||||||
|
} // namespace Itenso.Windows.Controls.ListViewLayout
|
||||||
|
// -- EOF -------------------------------------------------------------------
|
||||||
28
FSI.Lib/NLogViewer/Helper/PredicateBuilder.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
namespace DJ.Helper
|
||||||
|
{
|
||||||
|
public static class PredicateBuilder
|
||||||
|
{
|
||||||
|
public static Expression<Func<T, bool>> True<T> () { return f => true; }
|
||||||
|
public static Expression<Func<T, bool>> False<T> () { return f => false; }
|
||||||
|
|
||||||
|
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
|
||||||
|
Expression<Func<T, bool>> expr2)
|
||||||
|
{
|
||||||
|
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
|
||||||
|
return Expression.Lambda<Func<T, bool>>
|
||||||
|
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
|
||||||
|
Expression<Func<T, bool>> expr2)
|
||||||
|
{
|
||||||
|
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
|
||||||
|
return Expression.Lambda<Func<T, bool>>
|
||||||
|
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
FSI.Lib/NLogViewer/Images/Glyphs/SortDownArrow.png
Normal file
|
After Width: | Height: | Size: 264 B |
BIN
FSI.Lib/NLogViewer/Images/Glyphs/SortUpArrow.png
Normal file
|
After Width: | Height: | Size: 278 B |
BIN
FSI.Lib/NLogViewer/Images/Large/Add.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Context.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Debug.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/DebugSource.png
Normal file
|
After Width: | Height: | Size: 984 B |
BIN
FSI.Lib/NLogViewer/Images/Large/Error.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Exception.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Exit.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Export.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Fatal.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Info.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Network.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Open.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Save.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Settings.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Thread.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Trace.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Unknown.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
FSI.Lib/NLogViewer/Images/Large/Warning.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Add.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Debug.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Error.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Exception.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Exit.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Export.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Fatal.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Info.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Network.png
Normal file
|
After Width: | Height: | Size: 787 B |
BIN
FSI.Lib/NLogViewer/Images/Medium/Open.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Save.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Settings.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Thread.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Trace.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Unknown.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
FSI.Lib/NLogViewer/Images/Medium/Warning.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/Add.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/Clear.png
Normal file
|
After Width: | Height: | Size: 475 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Clock.png
Normal file
|
After Width: | Height: | Size: 365 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Context.png
Normal file
|
After Width: | Height: | Size: 451 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Debug.png
Normal file
|
After Width: | Height: | Size: 774 B |
BIN
FSI.Lib/NLogViewer/Images/Small/DebugSource.png
Normal file
|
After Width: | Height: | Size: 400 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Error.png
Normal file
|
After Width: | Height: | Size: 782 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Exception.png
Normal file
|
After Width: | Height: | Size: 943 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Exit.png
Normal file
|
After Width: | Height: | Size: 629 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Export.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/Fatal.png
Normal file
|
After Width: | Height: | Size: 589 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Info.png
Normal file
|
After Width: | Height: | Size: 778 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Layout.png
Normal file
|
After Width: | Height: | Size: 372 B |
BIN
FSI.Lib/NLogViewer/Images/Small/MonoLightning.png
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Network.png
Normal file
|
After Width: | Height: | Size: 506 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Open.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/Pause.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/Save.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/ScrollDown.png
Normal file
|
After Width: | Height: | Size: 623 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Settings.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/Thread.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
FSI.Lib/NLogViewer/Images/Small/Trace.png
Normal file
|
After Width: | Height: | Size: 631 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Unknown.png
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
FSI.Lib/NLogViewer/Images/Small/Warning.png
Normal file
|
After Width: | Height: | Size: 813 B |
154
FSI.Lib/NLogViewer/NLogViewer.csproj
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6-windows</TargetFramework>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
<RootNamespace>DJ</RootNamespace>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
<PackageId>Sentinel.NLogViewer</PackageId>
|
||||||
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Images\Glyphs\SortDownArrow.png" />
|
||||||
|
<None Remove="Images\Glyphs\SortUpArrow.png" />
|
||||||
|
<None Remove="Images\Large\Add.png" />
|
||||||
|
<None Remove="Images\Large\Context.png" />
|
||||||
|
<None Remove="Images\Large\Debug.png" />
|
||||||
|
<None Remove="Images\Large\DebugSource.png" />
|
||||||
|
<None Remove="Images\Large\Error.png" />
|
||||||
|
<None Remove="Images\Large\Exception.png" />
|
||||||
|
<None Remove="Images\Large\Exit.png" />
|
||||||
|
<None Remove="Images\Large\Export.png" />
|
||||||
|
<None Remove="Images\Large\Fatal.png" />
|
||||||
|
<None Remove="Images\Large\Info.png" />
|
||||||
|
<None Remove="Images\Large\Network.png" />
|
||||||
|
<None Remove="Images\Large\Open.png" />
|
||||||
|
<None Remove="Images\Large\Save.png" />
|
||||||
|
<None Remove="Images\Large\Settings.png" />
|
||||||
|
<None Remove="Images\Large\Thread.png" />
|
||||||
|
<None Remove="Images\Large\Trace.png" />
|
||||||
|
<None Remove="Images\Large\Unknown.png" />
|
||||||
|
<None Remove="Images\Large\Warning.png" />
|
||||||
|
<None Remove="Images\Medium\Add.png" />
|
||||||
|
<None Remove="Images\Medium\Debug.png" />
|
||||||
|
<None Remove="Images\Medium\Error.png" />
|
||||||
|
<None Remove="Images\Medium\Exception.png" />
|
||||||
|
<None Remove="Images\Medium\Exit.png" />
|
||||||
|
<None Remove="Images\Medium\Export.png" />
|
||||||
|
<None Remove="Images\Medium\Fatal.png" />
|
||||||
|
<None Remove="Images\Medium\Info.png" />
|
||||||
|
<None Remove="Images\Medium\Network.png" />
|
||||||
|
<None Remove="Images\Medium\Open.png" />
|
||||||
|
<None Remove="Images\Medium\Save.png" />
|
||||||
|
<None Remove="Images\Medium\Settings.png" />
|
||||||
|
<None Remove="Images\Medium\Thread.png" />
|
||||||
|
<None Remove="Images\Medium\Trace.png" />
|
||||||
|
<None Remove="Images\Medium\Unknown.png" />
|
||||||
|
<None Remove="Images\Medium\Warning.png" />
|
||||||
|
<None Remove="Images\Small\Add.png" />
|
||||||
|
<None Remove="Images\Small\Clear.png" />
|
||||||
|
<None Remove="Images\Small\Clock.png" />
|
||||||
|
<None Remove="Images\Small\Context.png" />
|
||||||
|
<None Remove="Images\Small\Debug.png" />
|
||||||
|
<None Remove="Images\Small\DebugSource.png" />
|
||||||
|
<None Remove="Images\Small\Error.png" />
|
||||||
|
<None Remove="Images\Small\Exception.png" />
|
||||||
|
<None Remove="Images\Small\Exit.png" />
|
||||||
|
<None Remove="Images\Small\Export.png" />
|
||||||
|
<None Remove="Images\Small\Fatal.png" />
|
||||||
|
<None Remove="Images\Small\Info.png" />
|
||||||
|
<None Remove="Images\Small\Layout.png" />
|
||||||
|
<None Remove="Images\Small\MonoLightning.png" />
|
||||||
|
<None Remove="Images\Small\Network.png" />
|
||||||
|
<None Remove="Images\Small\Open.png" />
|
||||||
|
<None Remove="Images\Small\Pause.png" />
|
||||||
|
<None Remove="Images\Small\Save.png" />
|
||||||
|
<None Remove="Images\Small\ScrollDown.png" />
|
||||||
|
<None Remove="Images\Small\Settings.png" />
|
||||||
|
<None Remove="Images\Small\Thread.png" />
|
||||||
|
<None Remove="Images\Small\Trace.png" />
|
||||||
|
<None Remove="Images\Small\Unknown.png" />
|
||||||
|
<None Remove="Images\Small\Warning.png" />
|
||||||
|
<None Remove="NLogViewer.xaml" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="GitVersion.MsBuild" Version="5.10.3">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NLog" Version="5.0.1" />
|
||||||
|
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="Images\Glyphs\SortDownArrow.png" />
|
||||||
|
<Resource Include="Images\Glyphs\SortUpArrow.png" />
|
||||||
|
<Resource Include="Images\Large\Add.png" />
|
||||||
|
<Resource Include="Images\Large\Context.png" />
|
||||||
|
<Resource Include="Images\Large\Debug.png" />
|
||||||
|
<Resource Include="Images\Large\DebugSource.png" />
|
||||||
|
<Resource Include="Images\Large\Error.png" />
|
||||||
|
<Resource Include="Images\Large\Exception.png" />
|
||||||
|
<Resource Include="Images\Large\Exit.png" />
|
||||||
|
<Resource Include="Images\Large\Export.png" />
|
||||||
|
<Resource Include="Images\Large\Fatal.png" />
|
||||||
|
<Resource Include="Images\Large\Info.png" />
|
||||||
|
<Resource Include="Images\Large\Network.png" />
|
||||||
|
<Resource Include="Images\Large\Open.png" />
|
||||||
|
<Resource Include="Images\Large\Save.png" />
|
||||||
|
<Resource Include="Images\Large\Settings.png" />
|
||||||
|
<Resource Include="Images\Large\Thread.png" />
|
||||||
|
<Resource Include="Images\Large\Trace.png" />
|
||||||
|
<Resource Include="Images\Large\Unknown.png" />
|
||||||
|
<Resource Include="Images\Large\Warning.png" />
|
||||||
|
<Resource Include="Images\Medium\Add.png" />
|
||||||
|
<Resource Include="Images\Medium\Debug.png" />
|
||||||
|
<Resource Include="Images\Medium\Error.png" />
|
||||||
|
<Resource Include="Images\Medium\Exception.png" />
|
||||||
|
<Resource Include="Images\Medium\Exit.png" />
|
||||||
|
<Resource Include="Images\Medium\Export.png" />
|
||||||
|
<Resource Include="Images\Medium\Fatal.png" />
|
||||||
|
<Resource Include="Images\Medium\Info.png" />
|
||||||
|
<Resource Include="Images\Medium\Network.png" />
|
||||||
|
<Resource Include="Images\Medium\Open.png" />
|
||||||
|
<Resource Include="Images\Medium\Save.png" />
|
||||||
|
<Resource Include="Images\Medium\Settings.png" />
|
||||||
|
<Resource Include="Images\Medium\Thread.png" />
|
||||||
|
<Resource Include="Images\Medium\Trace.png" />
|
||||||
|
<Resource Include="Images\Medium\Unknown.png" />
|
||||||
|
<Resource Include="Images\Medium\Warning.png" />
|
||||||
|
<Resource Include="Images\Small\Add.png" />
|
||||||
|
<Resource Include="Images\Small\Clear.png" />
|
||||||
|
<Resource Include="Images\Small\Clock.png" />
|
||||||
|
<Resource Include="Images\Small\Context.png" />
|
||||||
|
<Resource Include="Images\Small\Debug.png" />
|
||||||
|
<Resource Include="Images\Small\DebugSource.png" />
|
||||||
|
<Resource Include="Images\Small\Error.png" />
|
||||||
|
<Resource Include="Images\Small\Exception.png" />
|
||||||
|
<Resource Include="Images\Small\Exit.png" />
|
||||||
|
<Resource Include="Images\Small\Export.png" />
|
||||||
|
<Resource Include="Images\Small\Fatal.png" />
|
||||||
|
<Resource Include="Images\Small\Info.png" />
|
||||||
|
<Resource Include="Images\Small\Layout.png" />
|
||||||
|
<Resource Include="Images\Small\MonoLightning.png" />
|
||||||
|
<Resource Include="Images\Small\Network.png" />
|
||||||
|
<Resource Include="Images\Small\Open.png" />
|
||||||
|
<Resource Include="Images\Small\Pause.png" />
|
||||||
|
<Resource Include="Images\Small\Save.png" />
|
||||||
|
<Resource Include="Images\Small\ScrollDown.png" />
|
||||||
|
<Resource Include="Images\Small\Settings.png" />
|
||||||
|
<Resource Include="Images\Small\Thread.png" />
|
||||||
|
<Resource Include="Images\Small\Trace.png" />
|
||||||
|
<Resource Include="Images\Small\Unknown.png" />
|
||||||
|
<Resource Include="Images\Small\Warning.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="NLogView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
213
FSI.Lib/NLogViewer/NLogViewer.xaml
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
<UserControl x:Class="DJ.NLogViewer"
|
||||||
|
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:dj="clr-namespace:DJ"
|
||||||
|
xmlns:nLog="clr-namespace:NLog;assembly=NLog"
|
||||||
|
xmlns:listViewLayoutManager="clr-namespace:DJ.Helper.ListViewLayoutManager"
|
||||||
|
xmlns:xamlMultiValueConverter="clr-namespace:DJ.XamlMultiValueConverter"
|
||||||
|
xmlns:helper="clr-namespace:DJ.Helper"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="1"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Margin="0,5,0,5">
|
||||||
|
<ToggleButton
|
||||||
|
Width="120"
|
||||||
|
Height="20"
|
||||||
|
IsChecked="{Binding Path=AutoScroll, Mode=TwoWay}">
|
||||||
|
<ToggleButton.Content>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Source="Images/Small/ScrollDown.png"
|
||||||
|
RenderOptions.BitmapScalingMode="HighQuality" Stretch="Uniform" />
|
||||||
|
<TextBlock Text="Auto-Scroll" VerticalAlignment="Center" Margin="5,0,0,0" />
|
||||||
|
</StackPanel>
|
||||||
|
</ToggleButton.Content>
|
||||||
|
</ToggleButton>
|
||||||
|
<Button
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
Width="120"
|
||||||
|
Height="20"
|
||||||
|
Command="{Binding Path=ClearCommand}">
|
||||||
|
<Button.Content>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Source="Images/Small/Clear.png"
|
||||||
|
RenderOptions.BitmapScalingMode="HighQuality" Stretch="Uniform" />
|
||||||
|
<TextBlock Text="Clear" VerticalAlignment="Center" Margin="5,0,0,0" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
<ToggleButton
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
Width="120"
|
||||||
|
Height="20"
|
||||||
|
IsChecked="{Binding Path=Pause, Mode=TwoWay}">
|
||||||
|
<ToggleButton.Content>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Source="Images/Small/Pause.png"
|
||||||
|
RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Uniform" />
|
||||||
|
<TextBlock Text="Pause" VerticalAlignment="Center" Margin="5,0,0,0" />
|
||||||
|
</StackPanel>
|
||||||
|
</ToggleButton.Content>
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
x:Name="ListView"
|
||||||
|
Grid.Row="2"
|
||||||
|
ItemsSource="{Binding Path=LogEvents.View, IsAsync=True}"
|
||||||
|
BorderThickness="0"
|
||||||
|
ScrollViewer.CanContentScroll="True"
|
||||||
|
listViewLayoutManager:ListViewLayoutManager.Enabled="true">
|
||||||
|
<ListView.Resources>
|
||||||
|
<xamlMultiValueConverter:ILogEventResolverToStringConverter x:Key="ILogEventResolverToStringConverter"/>
|
||||||
|
</ListView.Resources>
|
||||||
|
<ListView.ItemContainerStyle>
|
||||||
|
<Style TargetType="ListViewItem">
|
||||||
|
<Setter Property="BorderBrush" Value="Black" />
|
||||||
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Trace}">
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=TraceBackground}" />
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=TraceForeground}" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Debug}">
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=DebugForeground}" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=DebugBackground}" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Info}">
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=InfoForeground}" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=InfoBackground}" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Warn}">
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=WarnForeground}" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=WarnBackground}" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Error}">
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=ErrorForeground}" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=ErrorBackground}" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Fatal}">
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=FatalForeground}" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}, Path=FatalBackground}" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</ListView.ItemContainerStyle>
|
||||||
|
<ListView.View>
|
||||||
|
<helper:AutoSizedGridView>
|
||||||
|
<GridViewColumn Header="ID" Width="40">
|
||||||
|
<GridViewColumn.DisplayMemberBinding>
|
||||||
|
<MultiBinding Converter="{StaticResource ILogEventResolverToStringConverter}">
|
||||||
|
<Binding Path="."/>
|
||||||
|
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}" Path="IdResolver"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</GridViewColumn.DisplayMemberBinding>
|
||||||
|
</GridViewColumn>
|
||||||
|
<GridViewColumn Header="Level" Width="Auto">
|
||||||
|
<GridViewColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Image x:Name="Image" RenderOptions.BitmapScalingMode="Linear"
|
||||||
|
Height="18" VerticalAlignment="Center" HorizontalAlignment="Center" />
|
||||||
|
<DataTemplate.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Trace}">
|
||||||
|
<Setter TargetName="Image" Property="Source"
|
||||||
|
Value="Images/Small/Trace.png" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Debug}">
|
||||||
|
<Setter TargetName="Image" Property="Source"
|
||||||
|
Value="Images/Small/Debug.png" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Info}">
|
||||||
|
<Setter TargetName="Image" Property="Source"
|
||||||
|
Value="Images/Small/Info.png" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Warn}">
|
||||||
|
<Setter TargetName="Image" Property="Source"
|
||||||
|
Value="Images/Small/Warning.png" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Error}">
|
||||||
|
<Setter TargetName="Image" Property="Source"
|
||||||
|
Value="Images/Small/Error.png" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Level}"
|
||||||
|
Value="{x:Static nLog:LogLevel.Fatal}">
|
||||||
|
<Setter TargetName="Image" Property="Source"
|
||||||
|
Value="Images/Small/Fatal.png" />
|
||||||
|
</DataTrigger>
|
||||||
|
</DataTemplate.Triggers>
|
||||||
|
</DataTemplate>
|
||||||
|
</GridViewColumn.CellTemplate>
|
||||||
|
</GridViewColumn>
|
||||||
|
<GridViewColumn Header="TimeStamp" Width="Auto">
|
||||||
|
<GridViewColumn.DisplayMemberBinding>
|
||||||
|
<MultiBinding Converter="{StaticResource ILogEventResolverToStringConverter}">
|
||||||
|
<Binding Path="."/>
|
||||||
|
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}" Path="TimeStampResolver"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</GridViewColumn.DisplayMemberBinding>
|
||||||
|
</GridViewColumn>
|
||||||
|
<GridViewColumn Header="LoggerName" Width="Auto">
|
||||||
|
<GridViewColumn.DisplayMemberBinding>
|
||||||
|
<MultiBinding Converter="{StaticResource ILogEventResolverToStringConverter}">
|
||||||
|
<Binding Path="."/>
|
||||||
|
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}" Path="LoggerNameResolver"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</GridViewColumn.DisplayMemberBinding>
|
||||||
|
</GridViewColumn>
|
||||||
|
<GridViewColumn Header="Message" Width="Auto" listViewLayoutManager:RangeColumn.IsFillColumn="True">
|
||||||
|
<GridViewColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBox
|
||||||
|
IsReadOnly="True"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListViewItem}, Path=Foreground}">
|
||||||
|
<TextBox.Text>
|
||||||
|
<MultiBinding Converter="{StaticResource ILogEventResolverToStringConverter}">
|
||||||
|
<Binding Path="." Mode="OneWay"/>
|
||||||
|
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=dj:NLogViewer}" Path="MessageResolver"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</TextBox.Text>
|
||||||
|
</TextBox>
|
||||||
|
</DataTemplate>
|
||||||
|
</GridViewColumn.CellTemplate>
|
||||||
|
</GridViewColumn>
|
||||||
|
</helper:AutoSizedGridView>
|
||||||
|
</ListView.View>
|
||||||
|
</ListView>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
543
FSI.Lib/NLogViewer/NLogViewer.xaml.cs
Normal file
@@ -0,0 +1,543 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive.Concurrency;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using DJ.Extensions;
|
||||||
|
using DJ.Resolver;
|
||||||
|
using DJ.Targets;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaktionslogik für NLogViewer.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class NLogViewer : UserControl
|
||||||
|
{
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Dependency Properties
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Dependency Properties
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Colors
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
#region Colors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The background for the trace output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush TraceBackground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(TraceBackgroundProperty);
|
||||||
|
set => SetValue(TraceBackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="TraceBackground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty TraceBackgroundProperty =
|
||||||
|
DependencyProperty.Register("TraceBackground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata((Brush) (new BrushConverter().ConvertFrom("#D3D3D3"))));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The foreground for the trace output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush TraceForeground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(TraceForegroundProperty);
|
||||||
|
set => SetValue(TraceForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="TraceForeground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty TraceForegroundProperty =
|
||||||
|
DependencyProperty.Register("TraceForeground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata((Brush) (new BrushConverter().ConvertFrom("#042271"))));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The background for the debug output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush DebugBackground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(DebugBackgroundProperty);
|
||||||
|
set => SetValue(DebugBackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="DebugBackground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty DebugBackgroundProperty =
|
||||||
|
DependencyProperty.Register("DebugBackground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata((Brush) (new BrushConverter().ConvertFrom("#90EE90"))));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The foreground for the debug output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush DebugForeground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(DebugForegroundProperty);
|
||||||
|
set => SetValue(DebugForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="DebugForeground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty DebugForegroundProperty =
|
||||||
|
DependencyProperty.Register("DebugForeground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata((Brush) (new BrushConverter().ConvertFrom("#042271"))));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The background for the info output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush InfoBackground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(InfoBackgroundProperty);
|
||||||
|
set => SetValue(InfoBackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="InfoBackground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty InfoBackgroundProperty = DependencyProperty.Register("InfoBackground",
|
||||||
|
typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata((Brush) (new BrushConverter().ConvertFrom("#0000FF"))));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The foreground for the info output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush InfoForeground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(InfoForegroundProperty);
|
||||||
|
set => SetValue(InfoForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="InfoForeground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty InfoForegroundProperty = DependencyProperty.Register("InfoForeground",
|
||||||
|
typeof(Brush), typeof(NLogViewer), new PropertyMetadata(Brushes.White));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The background for the warn output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush WarnBackground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(WarnBackgroundProperty);
|
||||||
|
set => SetValue(WarnBackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="WarnBackground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty WarnBackgroundProperty = DependencyProperty.Register("WarnBackground",
|
||||||
|
typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata((Brush) (new BrushConverter().ConvertFrom("#FFFF00"))));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The foreground for the warn output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush WarnForeground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(WarnForegroundProperty);
|
||||||
|
set => SetValue(WarnForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="WarnForeground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty WarnForegroundProperty = DependencyProperty.Register("WarnForeground",
|
||||||
|
typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata((Brush) (new BrushConverter().ConvertFrom("#324B5C"))));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The background for the error output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush ErrorBackground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(ErrorBackgroundProperty);
|
||||||
|
set => SetValue(ErrorBackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ErrorBackground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty ErrorBackgroundProperty =
|
||||||
|
DependencyProperty.Register("ErrorBackground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata(Brushes.Red));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The foreground for the error output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush ErrorForeground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(ErrorForegroundProperty);
|
||||||
|
set => SetValue(ErrorForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ErrorForeground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty ErrorForegroundProperty =
|
||||||
|
DependencyProperty.Register("ErrorForeground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata(Brushes.White));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The background for the fatal output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush FatalBackground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(FatalBackgroundProperty);
|
||||||
|
set => SetValue(FatalBackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="FatalBackground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty FatalBackgroundProperty =
|
||||||
|
DependencyProperty.Register("FatalBackground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata(Brushes.Black));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The foreground for the fatal output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerColors")]
|
||||||
|
public Brush FatalForeground
|
||||||
|
{
|
||||||
|
get => (Brush) GetValue(FatalForegroundProperty);
|
||||||
|
set => SetValue(FatalForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="FatalForeground"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty FatalForegroundProperty =
|
||||||
|
DependencyProperty.Register("FatalForeground", typeof(Brush), typeof(NLogViewer),
|
||||||
|
new PropertyMetadata(Brushes.Yellow));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// NLogViewer
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
#region NLogViewer
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is looking if any target with this name is configured and tries to link it
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewer")]
|
||||||
|
public string TargetName
|
||||||
|
{
|
||||||
|
get => (string)GetValue(TargetNameProperty);
|
||||||
|
set => SetValue(TargetNameProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="TargetName"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty TargetNameProperty = DependencyProperty.Register("TargetName", typeof(string), typeof(NLogViewer), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Private DP to bind to the gui
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewer")]
|
||||||
|
public CollectionViewSource LogEvents
|
||||||
|
{
|
||||||
|
get => (CollectionViewSource) GetValue(LogEventsProperty);
|
||||||
|
private set => SetValue(LogEventsProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="LogEvents"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty LogEventsProperty = DependencyProperty.Register("LogEvents",
|
||||||
|
typeof(CollectionViewSource), typeof(NLogViewer), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Automatically scroll to the newest entry
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewer")]
|
||||||
|
public bool AutoScroll
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(AutoScrollProperty);
|
||||||
|
set => SetValue(AutoScrollProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="AutoScroll"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty AutoScrollProperty = DependencyProperty.Register("AutoScroll", typeof(bool), typeof(NLogViewer), new PropertyMetadata(true, AutoScrollChangedCallback));
|
||||||
|
|
||||||
|
private static void AutoScrollChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs args)
|
||||||
|
{
|
||||||
|
if (d is NLogViewer instance)
|
||||||
|
{
|
||||||
|
instance.OnAutoScrollChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnAutoScrollChanged()
|
||||||
|
{
|
||||||
|
if (AutoScroll)
|
||||||
|
ListView?.ScrollToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delele all entries
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewer")]
|
||||||
|
public ICommand ClearCommand
|
||||||
|
{
|
||||||
|
get => (ICommand) GetValue(ClearCommandProperty);
|
||||||
|
set => SetValue(ClearCommandProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ClearCommand"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty ClearCommandProperty = DependencyProperty.Register("ClearCommand",
|
||||||
|
typeof(ICommand), typeof(NLogViewer), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stop logging
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewer")]
|
||||||
|
public bool Pause
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(PauseProperty);
|
||||||
|
set => SetValue(PauseProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="Pause"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty PauseProperty = DependencyProperty.Register("Pause", typeof(bool), typeof(NLogViewer), new PropertyMetadata(false));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum number of entries before automatic cleaning is performed. There is a hysteresis of 100 entries which must be exceeded.
|
||||||
|
/// Example: <see cref="MaxCount"/> is '1000'. Then after '1100' entries, everything until '1000' is deleted.
|
||||||
|
/// If set to '0' or less, it is deactivated
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewer")]
|
||||||
|
public int MaxCount
|
||||||
|
{
|
||||||
|
get => (int)GetValue(MaxCountProperty);
|
||||||
|
set => SetValue(MaxCountProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="MaxCount"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty MaxCountProperty = DependencyProperty.Register("MaxCount", typeof(int), typeof(NLogViewer), new PropertyMetadata(5000));
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Resolver
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
#region Resolver
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ILogEventInfoResolver"/> to format the id
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerResolver")]
|
||||||
|
public ILogEventInfoResolver IdResolver
|
||||||
|
{
|
||||||
|
get => (ILogEventInfoResolver)GetValue(IdResolverProperty);
|
||||||
|
set => SetValue(IdResolverProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="IdResolver"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty IdResolverProperty = DependencyProperty.Register("IdResolver", typeof(ILogEventInfoResolver), typeof(NLogViewer), new PropertyMetadata(new IdResolver()));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ILogEventInfoResolver"/> to format the timestamp output
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerResolver")]
|
||||||
|
public ILogEventInfoResolver TimeStampResolver
|
||||||
|
{
|
||||||
|
get => (ILogEventInfoResolver)GetValue(TimeStampResolverProperty);
|
||||||
|
set => SetValue(TimeStampResolverProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="TimeStampResolver"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty TimeStampResolverProperty = DependencyProperty.Register("TimeStampResolver", typeof(ILogEventInfoResolver), typeof(NLogViewer), new PropertyMetadata(new TimeStampResolver()));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ILogEventInfoResolver"/> to format the loggername
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerResolver")]
|
||||||
|
public ILogEventInfoResolver LoggerNameResolver
|
||||||
|
{
|
||||||
|
get => (ILogEventInfoResolver)GetValue(LoggerNameResolverProperty);
|
||||||
|
set => SetValue(LoggerNameResolverProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="LoggerNameResolver"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty LoggerNameResolverProperty = DependencyProperty.Register("LoggerNameResolver", typeof(ILogEventInfoResolver), typeof(NLogViewer), new PropertyMetadata(new LoggerNameResolver()));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ILogEventInfoResolver"/> to format the message
|
||||||
|
/// </summary>
|
||||||
|
[Category("NLogViewerResolver")]
|
||||||
|
public ILogEventInfoResolver MessageResolver
|
||||||
|
{
|
||||||
|
get => (ILogEventInfoResolver)GetValue(MessageResolverProperty);
|
||||||
|
set => SetValue(MessageResolverProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="MessageResolver"/> DependencyProperty.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty MessageResolverProperty = DependencyProperty.Register("MessageResolver", typeof(ILogEventInfoResolver), typeof(NLogViewer), new PropertyMetadata(new MessageResolver()));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Properties
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Public Properties
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Private Properties
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
private ObservableCollection<LogEventInfo> _LogEventInfos { get; } = new ObservableCollection<LogEventInfo>();
|
||||||
|
private IDisposable _Subscription;
|
||||||
|
private Window _ParentWindow;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Constructor
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public NLogViewer()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = this;
|
||||||
|
|
||||||
|
// save instance UID
|
||||||
|
Uid = GetHashCode().ToString();
|
||||||
|
|
||||||
|
if (DesignerProperties.GetIsInDesignMode(this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
LogEvents = new CollectionViewSource {Source = _LogEventInfos};
|
||||||
|
|
||||||
|
Loaded += _OnLoaded;
|
||||||
|
Unloaded += _OnUnloaded;
|
||||||
|
ClearCommand = new ActionCommand(_LogEventInfos.Clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _OnUnloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// look in logical and visual tree if the control has been removed
|
||||||
|
// If there is no parent window found before, we have a special case (https://github.com/dojo90/NLogViewer/issues/30) and just dispose it anyway
|
||||||
|
if (_ParentWindow.FindChildByUid<NLogViewer>(Uid) == null)
|
||||||
|
{
|
||||||
|
_Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ParentWindowOnClosed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
_Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _Dispose()
|
||||||
|
{
|
||||||
|
_Subscription?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _OnLoaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// removed loaded handler to prevent duplicate subscribing
|
||||||
|
Loaded -= _OnLoaded;
|
||||||
|
|
||||||
|
// add hook to parent window to dispose subscription
|
||||||
|
// use case:
|
||||||
|
// NLogViewer is used in a new window inside of a TabControl. If you switch the TabItems,
|
||||||
|
// the unloaded event is called and would dispose the subscription, even if the control is still alive.
|
||||||
|
if (Window.GetWindow(this) is { } window)
|
||||||
|
{
|
||||||
|
_ParentWindow = window;
|
||||||
|
_ParentWindow.Closed += _ParentWindowOnClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView.ScrollToEnd();
|
||||||
|
var target = CacheTarget.GetInstance(targetName: TargetName);
|
||||||
|
|
||||||
|
_Subscription = target.Cache.SubscribeOn(Scheduler.Default).Buffer(TimeSpan.FromMilliseconds(100)).Where (x => x.Any()).ObserveOn(new DispatcherSynchronizationContext(_ParentWindow.Dispatcher)).Subscribe(infos =>
|
||||||
|
{
|
||||||
|
if (Pause) return;
|
||||||
|
using (LogEvents.DeferRefresh())
|
||||||
|
{
|
||||||
|
foreach (LogEventInfo info in infos)
|
||||||
|
{
|
||||||
|
_LogEventInfos.Add(info);
|
||||||
|
}
|
||||||
|
if (MaxCount >= 0 & _LogEventInfos.Count - 100 > MaxCount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _LogEventInfos.Count - MaxCount; i++)
|
||||||
|
{
|
||||||
|
_LogEventInfos.RemoveAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AutoScroll)
|
||||||
|
{
|
||||||
|
ListView?.ScrollToEnd();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
12
FSI.Lib/NLogViewer/Resolver/ILogEventInfoResolver.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ.Resolver
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Default interface to resolve a <see cref="LogEventInfo"/> for your personal needs
|
||||||
|
/// </summary>
|
||||||
|
public interface ILogEventInfoResolver
|
||||||
|
{
|
||||||
|
string Resolve(LogEventInfo logEventInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
FSI.Lib/NLogViewer/Resolver/IdResolver.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ.Resolver
|
||||||
|
{
|
||||||
|
public class IdResolver : ILogEventInfoResolver
|
||||||
|
{
|
||||||
|
public string Resolve(LogEventInfo logEventInfo)
|
||||||
|
{
|
||||||
|
return logEventInfo.SequenceID.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
FSI.Lib/NLogViewer/Resolver/LoggerNameResolver.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ.Resolver
|
||||||
|
{
|
||||||
|
public class LoggerNameResolver : ILogEventInfoResolver
|
||||||
|
{
|
||||||
|
public string Resolve(LogEventInfo logEventInfo)
|
||||||
|
{
|
||||||
|
return logEventInfo.LoggerName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
FSI.Lib/NLogViewer/Resolver/MessageResolver.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System.Text;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ.Resolver
|
||||||
|
{
|
||||||
|
public class MessageResolver : ILogEventInfoResolver
|
||||||
|
{
|
||||||
|
public string Resolve(LogEventInfo logEventInfo)
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.Append(logEventInfo.FormattedMessage);
|
||||||
|
|
||||||
|
if (logEventInfo.Exception != null)
|
||||||
|
{
|
||||||
|
builder.AppendLine().Append(logEventInfo.Exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
FSI.Lib/NLogViewer/Resolver/TimeStampResolver.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ.Resolver
|
||||||
|
{
|
||||||
|
public class TimeStampResolver : ILogEventInfoResolver
|
||||||
|
{
|
||||||
|
public string Resolve(LogEventInfo logEventInfo)
|
||||||
|
{
|
||||||
|
return logEventInfo.TimeStamp.ToString("dd-MM-yyyy hh:mm:ss.fff");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
FSI.Lib/NLogViewer/ScrollingHelper.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace DJ
|
||||||
|
{
|
||||||
|
public static class ScrollingHelper
|
||||||
|
{
|
||||||
|
public static void ScrollToEnd(this ListView listView)
|
||||||
|
{
|
||||||
|
var scrollViewer = GetDescendantByType(listView, typeof(ScrollViewer)) as ScrollViewer;
|
||||||
|
scrollViewer?.ScrollToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Visual GetDescendantByType(Visual element, Type type)
|
||||||
|
{
|
||||||
|
if (element != null)
|
||||||
|
{
|
||||||
|
if (element.GetType() != type)
|
||||||
|
{
|
||||||
|
Visual foundElement = null;
|
||||||
|
(element as FrameworkElement)?.ApplyTemplate();
|
||||||
|
|
||||||
|
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
|
||||||
|
{
|
||||||
|
var visual = VisualTreeHelper.GetChild(element, i) as Visual;
|
||||||
|
foundElement = GetDescendantByType(visual, type);
|
||||||
|
if (foundElement != null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
93
FSI.Lib/NLogViewer/Targets/CacheTarget.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Subjects;
|
||||||
|
using DJ.Helper;
|
||||||
|
using NLog;
|
||||||
|
using NLog.Config;
|
||||||
|
using NLog.Targets;
|
||||||
|
|
||||||
|
namespace DJ.Targets
|
||||||
|
{
|
||||||
|
[Target(nameof(CacheTarget))]
|
||||||
|
public class CacheTarget : Target
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Look in the NLog.config if any target is already defined and returns it, otherwise a new one is registered
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="defaultMaxCount">The maximum entries which should be buffered. Is only used if no target is defined</param>
|
||||||
|
/// <param name="targetName">The name of the target you want to link with</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static CacheTarget GetInstance(int defaultMaxCount = 0, string targetName = null)
|
||||||
|
{
|
||||||
|
if(LogManager.Configuration == null)
|
||||||
|
LogManager.Configuration = new LoggingConfiguration();
|
||||||
|
|
||||||
|
var predicate = PredicateBuilder.True<Target>().And(t => t is CacheTarget);
|
||||||
|
if (!string.IsNullOrEmpty(targetName))
|
||||||
|
{
|
||||||
|
predicate = predicate.And(t => t.Name.Equals(targetName, StringComparison.CurrentCultureIgnoreCase) ||t.Name.Equals($"{targetName}_wrapped", StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
var target = (CacheTarget)LogManager.Configuration.AllTargets.FirstOrDefault(predicate.Compile());
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
target = new CacheTarget { MaxCount = defaultMaxCount, Name = targetName ?? nameof(CacheTarget)};
|
||||||
|
LogManager.Configuration.AddTarget(target.Name, target);
|
||||||
|
LogManager.Configuration.LoggingRules.Insert(0, new LoggingRule("*", LogLevel.FromString("Trace"), target));
|
||||||
|
LogManager.ReconfigExistingLoggers();
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Properties
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Public Properties
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum amount of entries held in buffer/cache
|
||||||
|
/// </summary>
|
||||||
|
public int MaxCount { get; set; } = 100;
|
||||||
|
|
||||||
|
public IObservable<LogEventInfo> Cache => _CacheSubject.AsObservable();
|
||||||
|
private readonly ReplaySubject<LogEventInfo> _CacheSubject;
|
||||||
|
|
||||||
|
// ##########################################################################################
|
||||||
|
// Private Properties
|
||||||
|
// ##########################################################################################
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// Constructor
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public CacheTarget()
|
||||||
|
{
|
||||||
|
_CacheSubject = new ReplaySubject<LogEventInfo>(MaxCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ##############################################################################################################################
|
||||||
|
// override
|
||||||
|
// ##############################################################################################################################
|
||||||
|
|
||||||
|
#region override
|
||||||
|
|
||||||
|
protected override void Write(LogEventInfo logEvent)
|
||||||
|
{
|
||||||
|
_CacheSubject.OnNext(logEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using DJ.Resolver;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace DJ.XamlMultiValueConverter
|
||||||
|
{
|
||||||
|
public class ILogEventResolverToStringConverter : IMultiValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (values[0] is LogEventInfo logEventInfo && values[1] is ILogEventInfoResolver resolver)
|
||||||
|
return resolver.Resolve(logEventInfo);
|
||||||
|
return "####";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
FSI.Lib/NLogViewer/global.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"sdk": {
|
||||||
|
"version": "6.0.101",
|
||||||
|
"rollForward": "disable"
|
||||||
|
}
|
||||||
|
}
|
||||||