Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AboutBoxWpf/AboutBoxWpf.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0-windows10.0.17763.0</TargetFramework>
<TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<Platforms>AnyCPU;x64;x86;ARM64</Platforms>
Expand Down
27 changes: 9 additions & 18 deletions EventLook/App.xaml
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
<!-- ReSharper disable once ObsoleteElementError -->
<Application x:Class="EventLook.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:EventLook"
StartupUri="View/MainWindow.xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d"
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
ThemeMode="System">
<Application.Resources>
<FontFamily x:Key="WingDings3">./Font/WINGDNG3.TTF#Wingdings 3</FontFamily>
<Style TargetType="Button">
<Setter Property="Width" Value="60" />
<Setter Property="Height" Value="22" />
<Setter Property="Margin" Value="5,0,0,0" />
</Style>
<Style TargetType="DataGrid">
<Setter Property="BorderBrush" Value="LightSteelBlue"/>
<Setter Property="HorizontalGridLinesBrush" Value="LightSteelBlue"/>
<Setter Property="VerticalGridLinesBrush" Value="LightSteelBlue"/>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightSkyBlue"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey }" Color="Black"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightSteelBlue"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey }" Color="Black"/>
</Style.Resources>
</Style>
<ResourceDictionary>
<FontFamily x:Key="WingDings3">./Font/WINGDNG3.TTF#Wingdings 3</FontFamily>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
4 changes: 2 additions & 2 deletions EventLook/EventLook.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.17763.0</TargetFramework>
<TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
Expand Down Expand Up @@ -50,7 +50,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.7.25104.5739" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="5.0.0" />
<PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers" Version="0.4.421302" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
Expand Down
29 changes: 29 additions & 0 deletions EventLook/Extensions/DependencyObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Windows;
using System.Windows.Media;

namespace EventLook.Extensions;

internal static class DependencyObjectExtensions
{
extension(DependencyObject tree)
{
// https://learn.microsoft.com/en-us/answers/questions/1806319/how-to-remove-the-clear-button-at-the-end-of-the-t
public DependencyObject FindChildElementByName(string sName)
{
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(tree); i++)
{
var child = VisualTreeHelper.GetChild(tree, i);

// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (child != null && (child as FrameworkElement)?.Name == sName)
return child;

var childInSubtree = FindChildElementByName(child, sName);
if (childInSubtree != null)
return childInSubtree;
}

return null;
}
}
}
24 changes: 24 additions & 0 deletions EventLook/Extensions/TextBoxExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Windows;
using System.Windows.Controls;

namespace EventLook.Extensions;

internal static class TextBoxExtensions
{
extension(TextBox textBox)
{
// https://learn.microsoft.com/en-us/answers/questions/1806319/how-to-remove-the-clear-button-at-the-end-of-the-t
public void DeleteFluentClearButton()
{
var childButton = textBox.FindChildElementByName("DeleteButton");
var parentGrid = (childButton as Control)?.Parent;
if (parentGrid != null)
{
if (childButton is UIElement childButtonElement)
{
(parentGrid as Grid)?.Children.Remove(childButtonElement);
}
}
}
}
}
50 changes: 50 additions & 0 deletions EventLook/View/DateTimePickerCustom.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<UserControl x:Class="EventLook.View.DateTimePickerCustom"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="Auto" Width="Auto"
Loaded="DateTimePickerCustom_Loaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<DatePicker x:Name="PartDatePicker"
SelectedDate="{Binding SelectedDate, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay, Converter={x:Null}}"
VerticalAlignment="Center"
Width="120">
<DatePicker.Style>
<Style TargetType="DatePicker" BasedOn="{StaticResource {x:Type DatePicker}}">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DatePicker.Style>
</DatePicker>

<TextBox Grid.Column="1" x:Name="PartTimeText"
Width="60" Margin="6,0,0,0" VerticalContentAlignment="Center"
Text="{Binding SelectedTimeString, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay}"
ToolTip="Enter time as HH:mm"
Loaded="PartTimeText_OnLoaded">
<TextBox.Style>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
<TextBox.InputBindings>
<KeyBinding Key="Enter"
Command="{Binding MoveFocusCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</TextBox.InputBindings>
</TextBox>
</Grid>
</UserControl>

147 changes: 147 additions & 0 deletions EventLook/View/DateTimePickerCustom.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using EventLook.Extensions;

namespace EventLook.View;

public sealed partial class DateTimePickerCustom
{
private bool isUpdating;

public DateTimePickerCustom()
{
InitializeComponent();
MoveFocusCommand = new RelayCommand(() => PartTimeText.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)));
}

public IRelayCommand MoveFocusCommand { get; }

#region Value dependency property

public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
nameof(Value),
typeof(DateTime),
typeof(DateTimePickerCustom),
new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged));

public DateTime Value
{
get => (DateTime)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (DateTimePickerCustom)d;
ctrl.UpdatePartsFromValue();
}

private void UpdatePartsFromValue()
{
if (isUpdating) return;
isUpdating = true;

SelectedDate = Value;
SelectedTimeString = TimeOnly.FromTimeSpan(Value.TimeOfDay).ToString(TimeFormat);

isUpdating = false;
}

#endregion Value dependency property

#region IsReadonly dependency property

public static readonly DependencyProperty IsReadOnlyProperty =
DependencyProperty.Register(nameof(IsReadOnly), typeof(bool), typeof(DateTimePickerCustom), new PropertyMetadata(false));

public bool IsReadOnly
{
get => (bool)GetValue(IsReadOnlyProperty);
set => SetValue(IsReadOnlyProperty, value);
}

#endregion IsReadonly dependency property

#region SelectedDate dependency property

public static readonly DependencyProperty SelectedDateProperty =
DependencyProperty.Register(
nameof(SelectedDate),
typeof(DateTime),
typeof(DateTimePickerCustom),
new FrameworkPropertyMetadata(DateTime.Now.Date, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedDateChanged));

public DateTime SelectedDate
{
get => (DateTime)GetValue(SelectedDateProperty);
set => SetValue(SelectedDateProperty, value);
}

private static void OnSelectedDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (DateTimePickerCustom)d;

if (ctrl.isUpdating) return;
ctrl.isUpdating = true;

ctrl.Value = (DateTime)e.NewValue + ctrl.Value.TimeOfDay;

ctrl.isUpdating = false;
}

#endregion SelectedDate dependency property

#region SelectedTimeString dependency property

private const string TimeFormat = "HH:mm";

public static readonly DependencyProperty SelectedTimeStringProperty =
DependencyProperty.Register(
nameof(SelectedTimeString),
typeof(string),
typeof(DateTimePickerCustom),
new FrameworkPropertyMetadata(TimeOnly.MinValue.ToString(TimeFormat), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedTimeStringChanged));

public string SelectedTimeString
{
get => (string)GetValue(SelectedTimeStringProperty);
set => SetValue(SelectedTimeStringProperty, value);
}

private static void OnSelectedTimeStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (DateTimePickerCustom)d;

if (ctrl.isUpdating) return;
ctrl.isUpdating = true;

// Allow HH:mm or HHmm format.
if (TimeOnly.TryParse((string)e.NewValue, out var time)
|| (e.NewValue is string { Length: 4 } str
&& TimeOnly.TryParse(str[..2] + ":" + str[2..], out time)))
{
// Ensure normalized time
ctrl.SelectedTimeString = time.ToString(TimeFormat);

ctrl.Value = ctrl.Value.Date + time.ToTimeSpan();
}

ctrl.isUpdating = false;
}

#endregion

private void DateTimePickerCustom_Loaded(object sender, RoutedEventArgs e)
{
UpdatePartsFromValue();
}

private void PartTimeText_OnLoaded(object sender, RoutedEventArgs e)
{
((TextBox)sender).DeleteFluentClearButton();
}
}
8 changes: 4 additions & 4 deletions EventLook/View/DetailWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
FocusManager.FocusedElement="{Binding ElementName=RichTextBoxXml}"
Title="Event Details" Height="550" Width="900">
<Window.InputBindings>
<KeyBinding Key="P" Modifiers="Ctrl" Command="{Binding UpCommand}"/>
<KeyBinding Key="N" Modifiers="Ctrl" Command="{Binding DownCommand}"/>
<KeyBinding Key="P" Modifiers="Control" Command="{Binding UpCommand}"/>
<KeyBinding Key="N" Modifiers="Control" Command="{Binding DownCommand}"/>
</Window.InputBindings>
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Command="{Binding UpCommand}" FontFamily="Segoe UI Symbol" Content="&#xE110;" FontSize="15" Width="30" Height="30" Margin="10" ToolTip="Previous event (Ctrl+P)"/>
<Button Command="{Binding DownCommand}" FontFamily="Segoe UI Symbol" Content="&#xE1FD;" FontSize="15" Width="30" Height="30" Margin="10" ToolTip="Next event (Ctrl+N)"/>
<Button Command="{Binding UpCommand}" FontFamily="Segoe UI Symbol" Content="&#xE110;" FontSize="15" Width="30" Height="30" Margin="10" Padding="0" ToolTip="Previous event (Ctrl+P)"/>
<Button Command="{Binding DownCommand}" FontFamily="Segoe UI Symbol" Content="&#xE1FD;" FontSize="15" Width="30" Height="30" Margin="10" Padding="0" ToolTip="Next event (Ctrl+N)"/>
</StackPanel>
<RichTextBox Name="RichTextBoxXml" FontSize="13"
local:TextBoxBehavior.HighlightedXml="{Binding EventXml, Mode=OneWay}"
Expand Down
6 changes: 3 additions & 3 deletions EventLook/View/LogPickerWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</DockPanel>
<CheckBox Margin="8" IsChecked="{Binding HidesEmptyLogs}">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsRunAsAdmin}" Value="False">
<Setter Property="Content" Value="Hide empty logs (try run as admin to view logs with blank record count)"/>
Expand All @@ -43,12 +43,12 @@
IsReadOnly="True"
PreviewKeyDown="dataGrid1_PreviewKeyDown">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick" />
</Style>
</DataGrid.Resources>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
</Style>
Expand Down
Loading
Loading