Projektdateien hinzufügen.
This commit is contained in:
90
VideoBrowser/Extensions/DictionaryExtension.cs
Normal file
90
VideoBrowser/Extensions/DictionaryExtension.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
namespace VideoBrowser.Extensions
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="DictionaryExtensions" />
|
||||
/// </summary>
|
||||
public static class DictionaryExtensions
|
||||
{
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// The Get
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dictionary">The dictionary<see cref="Dictionary{TKey, TValue}"/></param>
|
||||
/// <param name="key">The key<see cref="TKey"/></param>
|
||||
/// <param name="defaultValue">The defaultValue<see cref="TValue"/></param>
|
||||
/// <returns>The <see cref="TValue"/></returns>
|
||||
public static TValue Get<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
|
||||
{
|
||||
if (!dictionary.ContainsKey(key))
|
||||
{
|
||||
dictionary.Add(key, defaultValue);
|
||||
}
|
||||
|
||||
return dictionary[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Get
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dictionary">The dictionary<see cref="OrderedDictionary"/></param>
|
||||
/// <param name="key">The key<see cref="object"/></param>
|
||||
/// <param name="defaultValue">The defaultValue<see cref="object"/></param>
|
||||
/// <returns>The <see cref="TValue"/></returns>
|
||||
public static TValue Get<TValue>(this OrderedDictionary dictionary, object key, object defaultValue)
|
||||
{
|
||||
if (!dictionary.Contains(key))
|
||||
{
|
||||
dictionary.Add(key, defaultValue);
|
||||
}
|
||||
|
||||
return (TValue)dictionary[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Put
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dictionary">The dictionary<see cref="Dictionary{TKey, TValue}"/></param>
|
||||
/// <param name="key">The key<see cref="TKey"/></param>
|
||||
/// <param name="value">The value<see cref="TValue"/></param>
|
||||
public static void Put<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
|
||||
{
|
||||
if (dictionary.ContainsKey(key))
|
||||
{
|
||||
dictionary[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Put
|
||||
/// </summary>
|
||||
/// <param name="dictionary">The dictionary<see cref="OrderedDictionary"/></param>
|
||||
/// <param name="key">The key<see cref="object"/></param>
|
||||
/// <param name="value">The value<see cref="object"/></param>
|
||||
public static void Put(this OrderedDictionary dictionary, object key, object value)
|
||||
{
|
||||
if (dictionary.Contains(key))
|
||||
{
|
||||
dictionary[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
}
|
||||
}
|
||||
229
VideoBrowser/Extensions/EventBindingExtension.cs
Normal file
229
VideoBrowser/Extensions/EventBindingExtension.cs
Normal 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
|
||||
}
|
||||
}
|
||||
136
VideoBrowser/Extensions/FocusExtension.cs
Normal file
136
VideoBrowser/Extensions/FocusExtension.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
namespace VideoBrowser.Extensions
|
||||
{
|
||||
using System.Windows;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="FocusExtension" />.
|
||||
/// </summary>
|
||||
public static class FocusExtension
|
||||
{
|
||||
#region Fields
|
||||
|
||||
public static readonly DependencyProperty IsFocusedProperty =
|
||||
DependencyProperty.RegisterAttached(nameof(IsFocusedProperty).Name(), typeof(bool), typeof(FocusExtension), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsFocusedChanged));
|
||||
|
||||
public static readonly DependencyProperty TrackFocusProperty =
|
||||
DependencyProperty.RegisterAttached(nameof(TrackFocusProperty).Name(), typeof(bool), typeof(FocusExtension), new PropertyMetadata(false, OnTrackFocusChanged));
|
||||
|
||||
#endregion Fields
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// The GetIsFocused.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <returns>The <see cref="bool"/>.</returns>
|
||||
public static bool GetIsFocused(DependencyObject obj) => (bool)obj.GetValue(IsFocusedProperty);
|
||||
|
||||
/// <summary>
|
||||
/// The GetTrackFocus.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <returns>The <see cref="bool"/>.</returns>
|
||||
public static bool GetTrackFocus(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(TrackFocusProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The SetIsFocused.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="value">The value<see cref="bool"/>.</param>
|
||||
public static void SetIsFocused(DependencyObject obj, bool value) => obj.SetValue(IsFocusedProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// The SetTrackFocus.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="value">The value<see cref="bool"/>.</param>
|
||||
public static void SetTrackFocus(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(TrackFocusProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnGotFocus.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender<see cref="object"/>.</param>
|
||||
/// <param name="e">The e<see cref="RoutedEventArgs"/>.</param>
|
||||
private static void OnGotFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!(sender is FrameworkElement element))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetIsFocused(element))
|
||||
{
|
||||
SetIsFocused(element, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnIsFocusedChanged.
|
||||
/// </summary>
|
||||
/// <param name="d">The d<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="e">The e<see cref="DependencyPropertyChangedEventArgs"/>.</param>
|
||||
private static void OnIsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var element = (FrameworkElement)d;
|
||||
var isFocused = (bool)e.NewValue;
|
||||
if (isFocused)
|
||||
{
|
||||
element.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnLostFocus.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender<see cref="object"/>.</param>
|
||||
/// <param name="e">The e<see cref="RoutedEventArgs"/>.</param>
|
||||
private static void OnLostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!(sender is FrameworkElement element))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetIsFocused(element))
|
||||
{
|
||||
SetIsFocused(element, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnTrackFocusChanged.
|
||||
/// </summary>
|
||||
/// <param name="d">The d<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="e">The e<see cref="DependencyPropertyChangedEventArgs"/>.</param>
|
||||
private static void OnTrackFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is FrameworkElement element))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var oldValue = (bool)e.OldValue;
|
||||
var newValue = (bool)e.NewValue;
|
||||
|
||||
if (!oldValue && newValue) // If changed from false to true
|
||||
{
|
||||
element.GotFocus += OnGotFocus;
|
||||
element.LostFocus += OnLostFocus;
|
||||
}
|
||||
else if (oldValue && !newValue) // If changed from true to false
|
||||
{
|
||||
element.GotFocus -= OnGotFocus;
|
||||
element.LostFocus -= OnLostFocus;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
}
|
||||
}
|
||||
134
VideoBrowser/Extensions/INotifyPropertyChangedExtension.cs
Normal file
134
VideoBrowser/Extensions/INotifyPropertyChangedExtension.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
namespace VideoBrowser.Extensions
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using VideoBrowser.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="INotifyPropertyChangedExtension" />
|
||||
/// </summary>
|
||||
public static class INotifyPropertyChangedExtension
|
||||
{
|
||||
#region Delegates
|
||||
|
||||
/// <summary>
|
||||
/// The PropertyChangedInvokerEventHandler
|
||||
/// </summary>
|
||||
/// <param name="propertyName">The <see cref="string"/></param>
|
||||
public delegate void PropertyChangedInvokerEventHandler(string propertyName);
|
||||
|
||||
#endregion Delegates
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the properties changed.
|
||||
/// </summary>
|
||||
/// <param name="instance">The INotifyPropertyChanged implementation.</param>
|
||||
/// <param name="invoker">The invoker.</param>
|
||||
/// <param name="propertyNames">The property name list.</param>
|
||||
public static void InvokePropertiesChanged(this INotifyPropertyChanged instance, PropertyChangedInvokerEventHandler invoker, params string[] propertyNames)
|
||||
{
|
||||
foreach (var propertyName in propertyNames)
|
||||
{
|
||||
invoker?.Invoke(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The IsMatch
|
||||
/// </summary>
|
||||
/// <param name="e">The <see cref="PropertyChangedEventArgs"/></param>
|
||||
/// <param name="propertyNames">The <see cref="string"/></param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public static bool IsMatch(this PropertyChangedEventArgs e, params string[] propertyNames)
|
||||
{
|
||||
var propertyName = e.PropertyName;
|
||||
foreach (var name in propertyNames)
|
||||
{
|
||||
if (propertyName == name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified invoker.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="instance">The instance.</param>
|
||||
/// <param name="invoker">The invoker.</param>
|
||||
/// <param name="field">The field.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="propertyName">Name of the property.</param>
|
||||
/// <param name="propertyNames">The other optional property names to notify.</param>
|
||||
/// <returns> True if old value and new value are different. </returns>
|
||||
public static bool Set<T>(this INotifyPropertyChanged instance, PropertyChangedInvokerEventHandler invoker, ref T field, T value, [CallerMemberName] string propertyName = null, params string[] propertyNames)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(field, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
field = value;
|
||||
invoker?.Invoke(propertyName);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Set
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender<see cref="INotifyPropertyChanged"/></param>
|
||||
/// <param name="propertyChanged">The propertyChanged<see cref="PropertyChangedEventHandler"/></param>
|
||||
/// <param name="field">The field<see cref="double"/></param>
|
||||
/// <param name="value">The value<see cref="double"/></param>
|
||||
/// <param name="range">The range<see cref="RangeDouble"/></param>
|
||||
/// <param name="propertyName">The propertyName<see cref="string"/></param>
|
||||
/// <param name="propertyNames">The propertyNames<see cref="string[]"/></param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public static bool Set(this INotifyPropertyChanged sender, PropertyChangedEventHandler propertyChanged, ref double field, double value, RangeDouble range, [CallerMemberName] string propertyName = null, params string[] propertyNames)
|
||||
{
|
||||
if (field.IsEqualTo(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value.IsInRange(range.Start, range.End))
|
||||
{
|
||||
field = value;
|
||||
}
|
||||
|
||||
propertyChanged?.Invoke(sender, new PropertyChangedEventArgs(propertyName));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Set
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The property type.</typeparam>
|
||||
/// <param name="sender">The sender.</param>
|
||||
/// <param name="propertyChanged">The property changed.</param>
|
||||
/// <param name="field">The field.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="propertyName">Name of the property.</param>
|
||||
/// <param name="propertyNames">The property names.</param>
|
||||
/// <returns> True if old value and new value are different. </returns>
|
||||
public static bool Set<T>(this INotifyPropertyChanged sender, PropertyChangedEventHandler propertyChanged, ref T field, T value, [CallerMemberName] string propertyName = null, params string[] propertyNames)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(field, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
field = value;
|
||||
propertyChanged?.Invoke(sender, new PropertyChangedEventArgs(propertyName));
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
}
|
||||
}
|
||||
31
VideoBrowser/Extensions/ListExtension.cs
Normal file
31
VideoBrowser/Extensions/ListExtension.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace VideoBrowser.Extensions
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="ListExtension" />.
|
||||
/// </summary>
|
||||
public static class ListExtension
|
||||
{
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// The ClearAndDispose.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">.</typeparam>
|
||||
/// <param name="list">The list<see cref="ICollection{T}"/>.</param>
|
||||
public static void ClearAndDispose<T>(this ICollection<T> list)
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
var disposableItem = item as IDisposable;
|
||||
disposableItem?.Dispose();
|
||||
}
|
||||
|
||||
list.Clear();
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
}
|
||||
}
|
||||
1564
VideoBrowser/Extensions/MathExtensions.cs
Normal file
1564
VideoBrowser/Extensions/MathExtensions.cs
Normal file
File diff suppressed because it is too large
Load Diff
155
VideoBrowser/Extensions/RangeExtension.cs
Normal file
155
VideoBrowser/Extensions/RangeExtension.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
namespace VideoBrowser.Extensions
|
||||
{
|
||||
using VideoBrowser.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="RangeExtension" />
|
||||
/// </summary>
|
||||
public static class RangeExtension
|
||||
{
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// The Center
|
||||
/// </summary>
|
||||
/// <param name="range">The range<see cref="RangeDouble"/></param>
|
||||
/// <returns>The <see cref="double"/></returns>
|
||||
public static double Center(this RangeDouble range)
|
||||
{
|
||||
var center = range.Start + range.Length() * 0.5;
|
||||
return center;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Contains
|
||||
/// </summary>
|
||||
/// <param name="container">The container<see cref="RangeDouble"/></param>
|
||||
/// <param name="range">The range<see cref="RangeDouble"/></param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public static bool Contains(this RangeDouble container, RangeDouble range)
|
||||
{
|
||||
var contains = range.Start.IsInRange(container.Start, container.End) && range.End.IsInRange(container.Start, container.End);
|
||||
return contains;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Contains
|
||||
/// </summary>
|
||||
/// <param name="container">The container<see cref="RangeInt"/></param>
|
||||
/// <param name="range">The range<see cref="RangeInt"/></param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public static bool Contains(this RangeInt container, RangeInt range)
|
||||
{
|
||||
var contains = range.Start.IsInRange(container.Start, container.End) && range.End.IsInRange(container.Start, container.End);
|
||||
return contains;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The IsEmpty
|
||||
/// </summary>
|
||||
/// <param name="range">The range<see cref="RangeDouble"/></param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public static bool IsEmpty(this RangeDouble range)
|
||||
{
|
||||
var isEmpty = range.Start.IsZero() && range.End.IsZero();
|
||||
return isEmpty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is in range] [the specified minimum].
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="min">The minimum.</param>
|
||||
/// <param name="max">The maximum.</param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public static bool IsInRange(this double value, double min, double max)
|
||||
{
|
||||
return (min < max) ? value >= min && value <= max : value >= max && value <= min;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The IsInRange
|
||||
/// </summary>
|
||||
/// <param name="value">The value<see cref="int"/></param>
|
||||
/// <param name="min">The min<see cref="int"/></param>
|
||||
/// <param name="max">The max<see cref="int"/></param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public static bool IsInRange(this int value, int min, int max)
|
||||
{
|
||||
return (min < max) ? value >= min && value <= max : value >= max && value <= min;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lengthes the specified range.
|
||||
/// </summary>
|
||||
/// <param name="range">The range.</param>
|
||||
/// <returns>The length in double.</returns>
|
||||
public static double Length(this RangeDouble range)
|
||||
{
|
||||
return range.End - range.Start;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Length
|
||||
/// </summary>
|
||||
/// <param name="range">The range<see cref="RangeInt"/></param>
|
||||
/// <returns>The <see cref="int"/></returns>
|
||||
public static int Length(this RangeInt range)
|
||||
{
|
||||
return range.End - range.Start;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The MoveInsideContainer
|
||||
/// </summary>
|
||||
/// <param name="range">The range<see cref="RangeDouble"/></param>
|
||||
/// <param name="container">The container<see cref="RangeDouble"/></param>
|
||||
/// <returns>The <see cref="RangeDouble"/></returns>
|
||||
public static RangeDouble MoveInsideContainer(this RangeDouble range, RangeDouble container)
|
||||
{
|
||||
if (container.Contains(range))
|
||||
{
|
||||
return range;
|
||||
}
|
||||
|
||||
var length = range.Length();
|
||||
if (length > container.Length())
|
||||
{
|
||||
length = container.Length();
|
||||
}
|
||||
|
||||
var rangeInside = range.Start < container.Start ? new RangeDouble(container.Start, container.Start + length) : new RangeDouble(container.End - length, container.End);
|
||||
return rangeInside;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Offset the range to the specified distance.
|
||||
/// </summary>
|
||||
/// <param name="range">The range<see cref="RangeDouble"/></param>
|
||||
/// <param name="distance">The distance<see cref="double"/></param>
|
||||
/// <param name="extentRange">The extentRange<see cref="RangeDouble"/></param>
|
||||
/// <returns>The <see cref="RangeDouble"/></returns>
|
||||
public static RangeDouble Offset(this RangeDouble range, double distance, RangeDouble extentRange)
|
||||
{
|
||||
var length = range.Length();
|
||||
if (extentRange.Length() < length)
|
||||
{
|
||||
length = extentRange.Length();
|
||||
}
|
||||
|
||||
var start = range.Start + distance;
|
||||
var end = start + length;
|
||||
var newRange = new RangeDouble(start, end);
|
||||
if (extentRange.Contains(newRange))
|
||||
{
|
||||
return newRange;
|
||||
}
|
||||
|
||||
return start < extentRange.Start
|
||||
? new RangeDouble(extentRange.Start, extentRange.Start + length)
|
||||
: new RangeDouble(extentRange.End - length, extentRange.End);
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
}
|
||||
}
|
||||
56
VideoBrowser/Extensions/StringExtension.cs
Normal file
56
VideoBrowser/Extensions/StringExtension.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
namespace VideoBrowser.Extensions
|
||||
{
|
||||
using VideoBrowser.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="StringExtension" />
|
||||
/// </summary>
|
||||
public static class StringExtension
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ByteSizeFormatProvider
|
||||
/// </summary>
|
||||
private static ByteFormatProvider ByteSizeFormatProvider { get; } = new ByteFormatProvider();
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Replace dependency property name to property name.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">The propertyName<see cref="string"/></param>
|
||||
/// <returns>The <see cref="string"/></returns>
|
||||
public static string Name(this string propertyName)
|
||||
{
|
||||
var name = propertyName.Replace("Property", string.Empty);
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The ToFormatedByte
|
||||
/// </summary>
|
||||
/// <param name="byteSize">The byteSize<see cref="int"/></param>
|
||||
/// <returns>The <see cref="string"/></returns>
|
||||
public static string ToFormatedByte(int byteSize)
|
||||
{
|
||||
var formated = string.Format(ByteSizeFormatProvider, "{0:fs}", byteSize);
|
||||
return formated;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The ToFormatedSpeed
|
||||
/// </summary>
|
||||
/// <param name="speed">The speed<see cref="int"/></param>
|
||||
/// <returns>The <see cref="string"/></returns>
|
||||
public static string ToFormatedSpeed(int speed)
|
||||
{
|
||||
var formated = string.Format(ByteSizeFormatProvider, "{0:s}", speed);
|
||||
return formated;
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
}
|
||||
}
|
||||
271
VideoBrowser/Extensions/TextBoxExtension.cs
Normal file
271
VideoBrowser/Extensions/TextBoxExtension.cs
Normal file
@@ -0,0 +1,271 @@
|
||||
namespace VideoBrowser.Extensions
|
||||
{
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using VideoBrowser.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="TextBoxExtension" />.
|
||||
/// </summary>
|
||||
public static class TextBoxExtension
|
||||
{
|
||||
#region Fields
|
||||
|
||||
public static readonly DependencyProperty CaretIndexProperty =
|
||||
DependencyProperty.RegisterAttached(nameof(CaretIndexProperty).Name(), typeof(int), typeof(TextBoxExtension), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCaretIndexChanged));
|
||||
|
||||
public static readonly DependencyProperty IsClickToSelectAllProperty =
|
||||
DependencyProperty.RegisterAttached(nameof(IsClickToSelectAllProperty).Name(), typeof(bool), typeof(TextBoxExtension), new PropertyMetadata(false, OnIsClickToSelectAllChanged));
|
||||
|
||||
public static readonly DependencyProperty SelectionLengthProperty =
|
||||
DependencyProperty.RegisterAttached(nameof(SelectionLengthProperty).Name(), typeof(int), typeof(TextBoxExtension), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectionLengthChanged));
|
||||
|
||||
public static readonly DependencyProperty SelectionStartProperty =
|
||||
DependencyProperty.RegisterAttached(nameof(SelectionStartProperty).Name(), typeof(int), typeof(TextBoxExtension), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectionStartChanged));
|
||||
|
||||
public static readonly DependencyProperty TrackCaretIndexProperty =
|
||||
DependencyProperty.RegisterAttached(nameof(TrackCaretIndexProperty).Name(), typeof(bool), typeof(TextBoxExtension), new PropertyMetadata(false, OnTrackCaretIndexChanged));
|
||||
|
||||
#endregion Fields
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// The GetCaretIndex.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <returns>The <see cref="int"/>.</returns>
|
||||
public static int GetCaretIndex(DependencyObject obj) => (int)obj.GetValue(CaretIndexProperty);
|
||||
|
||||
/// <summary>
|
||||
/// The GetIsClickToSelectAll.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <returns>The <see cref="bool"/>.</returns>
|
||||
public static bool GetIsClickToSelectAll(DependencyObject obj) => (bool)obj.GetValue(IsClickToSelectAllProperty);
|
||||
|
||||
/// <summary>
|
||||
/// The GetSelectionLength.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <returns>The <see cref="int"/>.</returns>
|
||||
public static int GetSelectionLength(DependencyObject obj) => (int)obj.GetValue(SelectionLengthProperty);
|
||||
|
||||
/// <summary>
|
||||
/// The GetSelectionStart.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <returns>The <see cref="int"/>.</returns>
|
||||
public static int GetSelectionStart(DependencyObject obj) => (int)obj.GetValue(SelectionStartProperty);
|
||||
|
||||
/// <summary>
|
||||
/// The GetTrackCaretIndex.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <returns>The <see cref="bool"/>.</returns>
|
||||
public static bool GetTrackCaretIndex(DependencyObject obj) => (bool)obj.GetValue(TrackCaretIndexProperty);
|
||||
|
||||
/// <summary>
|
||||
/// The SetCaretIndex.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="value">The value<see cref="int"/>.</param>
|
||||
public static void SetCaretIndex(DependencyObject obj, int value) => obj.SetValue(CaretIndexProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// The SetIsClickToSelectAll.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="value">The value<see cref="bool"/>.</param>
|
||||
public static void SetIsClickToSelectAll(DependencyObject obj, bool value) => obj.SetValue(IsClickToSelectAllProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// The SetSelectionLength.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="value">The value<see cref="int"/>.</param>
|
||||
public static void SetSelectionLength(DependencyObject obj, int value) => obj.SetValue(SelectionLengthProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// The SetSelectionStart.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="value">The value<see cref="int"/>.</param>
|
||||
public static void SetSelectionStart(DependencyObject obj, int value) => obj.SetValue(SelectionStartProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// The SetTrackCaretIndex.
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="value">The value<see cref="bool"/>.</param>
|
||||
public static void SetTrackCaretIndex(DependencyObject obj, bool value) => obj.SetValue(TrackCaretIndexProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// The OnCaretIndexChanged.
|
||||
/// </summary>
|
||||
/// <param name="d">The d<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="e">The e<see cref="DependencyPropertyChangedEventArgs"/>.</param>
|
||||
private static void OnCaretIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is TextBox textbox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var caretIndex = (int)e.NewValue;
|
||||
if (textbox.CaretIndex != caretIndex)
|
||||
{
|
||||
textbox.CaretIndex = caretIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnIsClickToSelectAllChanged.
|
||||
/// </summary>
|
||||
/// <param name="d">The d<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="e">The e<see cref="DependencyPropertyChangedEventArgs"/>.</param>
|
||||
private static void OnIsClickToSelectAllChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is TextBox textbox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var oldValue = (bool)e.OldValue;
|
||||
var newValue = (bool)e.NewValue;
|
||||
|
||||
if (!oldValue && newValue) // If changed from false to true
|
||||
{
|
||||
textbox.PreviewMouseLeftButtonDown += OnTextbox_PreviewMouseLeftButtonDown;
|
||||
textbox.MouseDoubleClick += OnTextbox_MouseDoubleClick;
|
||||
}
|
||||
else if (oldValue && !newValue) // If changed from true to false
|
||||
{
|
||||
textbox.PreviewMouseLeftButtonDown -= OnTextbox_PreviewMouseLeftButtonDown;
|
||||
textbox.MouseDoubleClick -= OnTextbox_MouseDoubleClick;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnSelectionChanged.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender<see cref="object"/>.</param>
|
||||
/// <param name="e">The e<see cref="RoutedEventArgs"/>.</param>
|
||||
private static void OnSelectionChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textbox)
|
||||
{
|
||||
SetCaretIndex(textbox, textbox.CaretIndex);
|
||||
SetSelectionStart(textbox, textbox.SelectionStart);
|
||||
SetSelectionLength(textbox, textbox.SelectionLength);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnSelectionLengthChanged.
|
||||
/// </summary>
|
||||
/// <param name="d">The d<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="e">The e<see cref="DependencyPropertyChangedEventArgs"/>.</param>
|
||||
private static void OnSelectionLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is TextBox textbox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectionLength = (int)e.NewValue;
|
||||
if (textbox.SelectionLength != selectionLength)
|
||||
{
|
||||
textbox.SelectionLength = selectionLength;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnSelectionStartChanged.
|
||||
/// </summary>
|
||||
/// <param name="d">The d<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="e">The e<see cref="DependencyPropertyChangedEventArgs"/>.</param>
|
||||
private static void OnSelectionStartChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is TextBox textbox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectionStart = (int)e.NewValue;
|
||||
if (textbox.SelectionStart != selectionStart)
|
||||
{
|
||||
textbox.SelectionStart = selectionStart;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnTextbox_MouseDoubleClick.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender<see cref="object"/>.</param>
|
||||
/// <param name="e">The e<see cref="MouseButtonEventArgs"/>.</param>
|
||||
private static void OnTextbox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (!(sender is TextBox textbox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UIThreadHelper.DelayedInvokeAsync(() =>
|
||||
{
|
||||
textbox.Focus();
|
||||
textbox.SelectAll();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnTextbox_PreviewMouseLeftButtonDown.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender<see cref="object"/>.</param>
|
||||
/// <param name="e">The e<see cref="MouseButtonEventArgs"/>.</param>
|
||||
private static void OnTextbox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (!(sender is TextBox textbox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!textbox.IsFocused)
|
||||
{
|
||||
UIThreadHelper.DelayedInvokeAsync(() =>
|
||||
{
|
||||
textbox.Focus();
|
||||
textbox.SelectAll();
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OnTrackCaretIndexChanged.
|
||||
/// </summary>
|
||||
/// <param name="d">The d<see cref="DependencyObject"/>.</param>
|
||||
/// <param name="e">The e<see cref="DependencyPropertyChangedEventArgs"/>.</param>
|
||||
private static void OnTrackCaretIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is TextBox textbox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var oldValue = (bool)e.OldValue;
|
||||
var newValue = (bool)e.NewValue;
|
||||
|
||||
if (!oldValue && newValue) // If changed from false to true
|
||||
{
|
||||
textbox.SelectionChanged += OnSelectionChanged;
|
||||
}
|
||||
else if (oldValue && !newValue) // If changed from true to false
|
||||
{
|
||||
textbox.SelectionChanged -= OnSelectionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user