This commit is contained in:
dan_clark@outlook.com
2022-03-23 15:44:32 +00:00
commit 2ac0e3ed26
129 changed files with 4197 additions and 0 deletions
@@ -0,0 +1,41 @@
using System.Reflection;
using System.Windows;
using TheXamlGuy.TaskbarGroup.Core;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public class DataTemplateFactory : IDataTemplateFactory
{
private readonly IDataTemplateCollection datatemplateCollection;
private readonly IServiceFactory serviceFactory;
public DataTemplateFactory(IDataTemplateCollection datatemplateCollection,
IServiceFactory serviceFactory)
{
this.datatemplateCollection = datatemplateCollection;
this.serviceFactory = serviceFactory;
}
public virtual DataTemplate? Create(Type dataType)
{
if (dataType is null) throw new ArgumentNullException(nameof(dataType));
if (!datatemplateCollection.TryGetValue(dataType, out Type? viewType))
{
var assembly = dataType.GetTypeInfo().Assembly;
viewType = Type.GetType($"{dataType.FullName?.Replace("ViewModel", "View")}, {assembly.FullName}");
}
if (viewType is not null)
{
var view = serviceFactory.Create<object>(viewType);
if (view is not null)
{
return TemplateGenerator.CreateDataTemplate(() => view);
}
}
return null;
}
}
}
@@ -0,0 +1,37 @@
using System;
using TheXamlGuy.TaskbarGroup.Core;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public class DispatcherTimer : IDispatcherTimer
{
private readonly System.Windows.Threading.DispatcherTimer timer;
private readonly Action actionDelegate;
public DispatcherTimer(Action actionDelegate, TimeSpan interval)
{
timer = new System.Windows.Threading.DispatcherTimer
{
Interval = interval
};
timer.Tick += OnTick;
this.actionDelegate = actionDelegate;
}
private void OnTick(object? sender, EventArgs args)
{
actionDelegate?.Invoke();
}
public void Start()
{
timer.Start();
}
public void Stop()
{
timer.Stop();
}
}
}
@@ -0,0 +1,13 @@
using System;
using TheXamlGuy.TaskbarGroup.Core;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public class DispatcherTimerFactory : IDispatcherTimerFactory
{
public IDispatcherTimer Create(Action actionDelegate, TimeSpan interval)
{
return new DispatcherTimer(actionDelegate, interval);
}
}
}
@@ -0,0 +1,82 @@
using System.Diagnostics;
using System.Windows;
using System.Windows.Shell;
using TheXamlGuy.TaskbarGroup.Core;
using Microsoft.WindowsAPICodePack.Shell;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public class FileDropTarget : IDropTarget<UIElement>
{
private UIElement? target;
private readonly IMessenger messenger;
public FileDropTarget(IMessenger messenger)
{
this.messenger = messenger;
}
public void Register(UIElement target)
{
if (this.target is not null)
{
target.DragOver -= OnDragOver;
target.DragEnter -= OnDragEnter;
target.Drop -= OnDrop;
}
this.target = target;
target.DragOver += OnDragOver;
target.DragEnter += OnDragEnter;
target.Drop += OnDrop;
}
private void OnDrop(object sender, DragEventArgs args)
{
String[] fileName = (String[])args.Data.GetFormats();
var ddd = ShellObjectCollection.FromDataObject((System.Runtime.InteropServices.ComTypes.IDataObject)args.Data);
//args.Handled = true;
//var fileName = GetFileName(args.Data);
//messenger.Publish<FileDropped>();
}
private string GetFileName(IDataObject data)
{
var filenames = (string[])data.GetData(DataFormats.FileDrop);
return filenames[0];
}
private bool IsFileDrop(IDataObject data)
{
return data.GetDataPresent(DataFormats.FileDrop);
}
private void OnDragEnter(object sender, DragEventArgs args)
{
if (IsFileDrop(args.Data))
{
args.Effects = DragDropEffects.Link;
}
else
{
args.Effects = DragDropEffects.None;
}
}
private void OnDragOver(object sender, DragEventArgs args)
{
if (IsFileDrop(args.Data))
{
args.Effects = DragDropEffects.Link;
}
else
{
args.Effects = DragDropEffects.None;
}
}
}
}
@@ -0,0 +1,9 @@
using System.Windows;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public interface IDataTemplateFactory
{
DataTemplate? Create(Type type);
}
}
@@ -0,0 +1,18 @@
using Microsoft.Extensions.DependencyInjection;
using TheXamlGuy.TaskbarGroup.Core;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddRequiredFoundation(this IServiceCollection serviceCollection)
{
return serviceCollection
.AddSingleton<TemplateSelector>()
.AddSingleton<IDataTemplateCollection>(new DataTemplateCollection(new Dictionary<Type, Type>()))
.AddSingleton<DataTemplateFactory>()
.AddSingleton<IDispatcherTimerFactory, DispatcherTimerFactory>()
.AddTransient<FileDropTarget>();
}
}
}
@@ -0,0 +1,20 @@
using System.Windows;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public static class TemplateGenerator
{
public static DataTemplate CreateDataTemplate(Func<object> factory)
{
var frameworkElementFactory = new FrameworkElementFactory(typeof(TemplateGeneratorControl));
frameworkElementFactory.SetValue(TemplateGeneratorControl.FactoryProperty, factory);
var dataTemplate = new DataTemplate(typeof(DependencyObject))
{
VisualTree = frameworkElementFactory
};
return dataTemplate;
}
}
}
@@ -0,0 +1,22 @@
using System.Windows;
using System.Windows.Controls;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
internal sealed class TemplateGeneratorControl : ContentControl
{
internal static readonly DependencyProperty FactoryProperty =
DependencyProperty.Register("Factory", typeof(Func<object>),
typeof(TemplateGeneratorControl), new PropertyMetadata(null,
OnFactoryPropertyChanged));
private static void OnFactoryPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
if (dependencyObject is TemplateGeneratorControl sender && args.NewValue is not null)
{
var factory = (Func<object>)args.NewValue;
sender.Content = factory();
}
}
}
}
@@ -0,0 +1,32 @@
using System.Windows;
using System.Windows.Controls;
using TheXamlGuy.TaskbarGroup.Core;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public class TemplateSelector : DataTemplateSelector, ITemplateSelector
{
private readonly DataTemplateFactory dataTemplateFactory;
public TemplateSelector(DataTemplateFactory dataTemplateFactory)
{
this.dataTemplateFactory = dataTemplateFactory;
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is not null)
{
var dataType = item.GetType();
var dataTemplate = dataTemplateFactory.Create(dataType);
if (dataTemplate is not null)
{
dataTemplate.Seal();
return dataTemplate;
}
}
return base.SelectTemplate(item, container);
}
}
}
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>10.0</LangVersion>
<Platforms>x64;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft-WindowsAPICodePack-Core" Version="1.1.4" />
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TheXamlGuy.TaskbarGroup.Core\TheXamlGuy.TaskbarGroup.Core.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,26 @@
using System.Windows;
using System.Windows.Media;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public static class VisualExtensions
{
private static Matrix GetDpi(this Visual visual)
{
var source = PresentationSource.FromVisual(visual);
if (source?.CompositionTarget != null) return (Matrix)source?.CompositionTarget.TransformToDevice;
return default;
}
public static double DpiY(this Visual visual)
{
return GetDpi(visual).M22;
}
public static double DpiX(this Visual visual)
{
return GetDpi(visual).M11;
}
}
}
@@ -0,0 +1,29 @@
using System;
using System.Windows;
using System.Windows.Interop;
using TheXamlGuy.TaskbarGroup.Core;
using Windows.Win32.Foundation;
namespace TheXamlGuy.TaskbarGroup.Foundation
{
public static class WindowExtensions
{
public static IntPtr GetHandle(this Window window)
{
return new WindowInteropHelper(window).Handle;
}
public static void MoveAndResize(this Window window, int x, int y, int width, int height)
{
var handle = window.GetHandle();
WindowHelper.MoveAndResize(new HWND(handle), x, y, width, height);
}
public static void BringToForeground(this Window window)
{
var handle = window.GetHandle();
WindowHelper.BringToForeground(new HWND(handle));
}
}
}