Projektdateien hinzufügen.

This commit is contained in:
Kevin Krüger
2023-07-24 12:00:34 +02:00
parent 656751e10b
commit 0d00a90942
210 changed files with 45049 additions and 0 deletions

View File

@@ -0,0 +1,229 @@
namespace VideoBrowser.Extensions
{
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Markup;
/// <summary>
/// Defines the <see cref="EventBindingExtension" />.
/// </summary>
[MarkupExtensionReturnType(typeof(Delegate))]
public class EventBindingExtension : MarkupExtension
{
#region Fields
/// <summary>
/// The command binder attached property.
/// </summary>
private static readonly DependencyProperty CommandBinderProperty =
DependencyProperty.RegisterAttached(nameof(CommandBinderProperty).Name(), typeof(ICommand), typeof(EventBindingExtension), new PropertyMetadata(null));
/// <summary>
/// The command parameter binder attached property.
/// </summary>
private static readonly DependencyProperty CommandParameterBinderProperty =
DependencyProperty.RegisterAttached(nameof(CommandParameterBinderProperty).Name(), typeof(object), typeof(EventBindingExtension), new PropertyMetadata(null));
/// <summary>
/// Name of the Command to be invoked when the event fires
/// </summary>
private readonly string _commandName;
#endregion Fields
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="EventBindingExtension"/> class.
/// </summary>
public EventBindingExtension()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="EventBindingExtension"/> class.
/// </summary>
/// <param name="command">The command<see cref="string"/>.</param>
public EventBindingExtension(string command)
{
this._commandName = command;
}
#endregion Constructors
#region Properties
/// <summary>
/// Gets or sets the Command.
/// </summary>
public Binding Command { get; set; }
/// <summary>
/// Gets or sets the CommandParameter.
/// </summary>
public Binding CommandParameter { get; set; }
/// <summary>
/// Gets or sets the Element.
/// </summary>
private DependencyObject Element { get; set; }
#endregion Properties
#region Methods
/// <summary>
/// The GetCommandBinder.
/// </summary>
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
/// <returns>The <see cref="ICommand"/>.</returns>
public static ICommand GetCommandBinder(DependencyObject obj)
{
return (ICommand)obj.GetValue(CommandBinderProperty);
}
/// <summary>
/// The GetCommandParameterBinder.
/// </summary>
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
/// <returns>The <see cref="object"/>.</returns>
public static object GetCommandParameterBinder(DependencyObject obj)
{
return obj.GetValue(CommandParameterBinderProperty);
}
/// <summary>
/// The SetCommandBinder.
/// </summary>
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
/// <param name="value">The value<see cref="ICommand"/>.</param>
public static void SetCommandBinder(DependencyObject obj, ICommand value)
{
obj.SetValue(CommandBinderProperty, value);
}
/// <summary>
/// The SetCommandParameterBinder.
/// </summary>
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
/// <param name="value">The value<see cref="object"/>.</param>
public static void SetCommandParameterBinder(DependencyObject obj, object value)
{
obj.SetValue(CommandParameterBinderProperty, value);
}
/// <summary>
/// The ProvideValue.
/// </summary>
/// <param name="serviceProvider">.</param>
/// <returns>.</returns>
public override object ProvideValue(IServiceProvider serviceProvider)
{
// Retrieve a reference to the InvokeCommand helper method declared below, using reflection
MethodInfo invokeCommand = GetType().GetMethod(nameof(InvokeCommand), BindingFlags.Instance | BindingFlags.NonPublic);
if (invokeCommand != null)
{
// Check if the current context is an event or a method call with two parameters
var target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (target != null)
{
this.Element = target.TargetObject as DependencyObject;
var property = target.TargetProperty;
if (property is EventInfo)
{
// If the context is an event, simply return the helper method as delegate
// (this delegate will be invoked when the event fires)
var eventHandlerType = (property as EventInfo).EventHandlerType;
return invokeCommand.CreateDelegate(eventHandlerType, this);
}
else if (property is MethodInfo)
{
// Some events are represented as method calls with 2 parameters:
// The first parameter is the control that acts as the event's sender,
// the second parameter is the actual event handler
var methodParameters = (property as MethodInfo).GetParameters();
if (methodParameters.Length == 2)
{
var eventHandlerType = methodParameters[1].ParameterType;
return invokeCommand.CreateDelegate(eventHandlerType, this);
}
}
}
}
throw new InvalidOperationException("The EventBinding markup extension is valid only in the context of events.");
}
/// <summary>
/// The GetDataContext.
/// </summary>
/// <param name="sender">The sender<see cref="object"/>.</param>
/// <returns>The <see cref="object"/>.</returns>
private object GetDataContext(object sender)
{
if (sender is FrameworkContentElement control)
{
return control.DataContext;
}
return sender is FrameworkElement element ? element.DataContext : null;
}
/// <summary>
/// The InvokeCommand.
/// </summary>
/// <param name="sender">.</param>
/// <param name="args">.</param>
private void InvokeCommand(object sender, EventArgs args)
{
var dataContext = this.GetDataContext(sender);
if (dataContext == null)
{
throw new NullReferenceException($"DataContext is null.");
}
object commandParameter = null;
if (this.CommandParameter != null)
{
BindingOperations.SetBinding(this.Element, CommandParameterBinderProperty, this.CommandParameter);
commandParameter = this.Element.GetValue(CommandParameterBinderProperty);
BindingOperations.ClearBinding(this.Element, CommandParameterBinderProperty);
}
var executeParameters = (sender, args, commandParameter);
if (!string.IsNullOrEmpty(_commandName) && dataContext != null)
{
// Find control's ViewModel
var viewmodel = dataContext;
if (viewmodel != null)
{
// Command must be declared as public property within ViewModel
var commandProperty = viewmodel.GetType().GetProperty(_commandName);
if (commandProperty != null && commandProperty.GetValue(viewmodel) is ICommand constructorCommand && constructorCommand.CanExecute(args))
{
// Execute Command and pass event arguments as parameter
constructorCommand.Execute(executeParameters);
return;
}
}
}
// Get the binding values.
BindingOperations.SetBinding(this.Element, CommandBinderProperty, this.Command);
var command = this.Element.GetValue(CommandBinderProperty);
BindingOperations.ClearBinding(this.Element, CommandBinderProperty);
// Execute the command.
if ((command is ICommand relayCommand) && relayCommand.CanExecute(commandParameter))
{
relayCommand.Execute(executeParameters);
}
}
#endregion Methods
}
}