diff --git a/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs b/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs
index 85e386c..ab49520 100644
--- a/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs
+++ b/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs
@@ -1,3 +1,4 @@
+using System.ComponentModel;
using System.Windows.Forms;
namespace BytecodeApi.Win32.Interop;
@@ -5,7 +6,7 @@ namespace BytecodeApi.Win32.Interop;
///
/// Provides data for the event.
///
-public sealed class KeyboardHookEventArgs : EventArgs
+public sealed class KeyboardHookEventArgs : HandledEventArgs
{
///
/// Gets the keycode of the pressed key.
@@ -19,10 +20,6 @@ public sealed class KeyboardHookEventArgs : EventArgs
/// Gets the key character, or '\0', if the key does not represent a printable character.
///
public char KeyChar { get; }
- ///
- /// Gets or sets a value indicating whether to cancel the keyboard event.
- ///
- public bool Handled { get; set; }
///
/// Initializes a new instance of the class.
diff --git a/BytecodeApi/Data/Pagination.cs b/BytecodeApi/Data/Pagination.cs
new file mode 100644
index 0000000..6b0ee39
--- /dev/null
+++ b/BytecodeApi/Data/Pagination.cs
@@ -0,0 +1,51 @@
+namespace BytecodeApi.Data;
+
+///
+/// Provides information about the pagination of a collection of items.
+///
+public sealed class Pagination
+{
+ ///
+ /// Gets or sets the zero based page index.
+ /// The default value is 0.
+ ///
+ public int Page { get; set; }
+ ///
+ /// Gets or sets the number of items included in a page.
+ /// The default value is 10.
+ ///
+ public int PageSize { get; set; }
+ ///
+ /// Gets or sets the total number of items, or , if the total number of items is unknown.
+ ///
+ public int? TotalCount { get; set; }
+ ///
+ /// Gets the total number of pages, or , if the total number of items is unknown.
+ ///
+ public int? PageCount => TotalCount is null or < 0 || PageSize <= 0 ? null : (TotalCount.Value + PageSize - 1) / PageSize;
+ ///
+ /// Gets the number of items to skip in order to get the items for the current page.
+ ///
+ public int Skip => Page * PageSize;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Pagination()
+ {
+ PageSize = 10;
+ }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The zero based page index.
+ /// The number of items included in a page.
+ public Pagination(int page, int pageSize) : this()
+ {
+ Check.ArgumentOutOfRangeEx.GreaterEqual0(page);
+ Check.ArgumentOutOfRangeEx.Greater0(pageSize);
+
+ Page = page;
+ PageSize = pageSize;
+ }
+}
\ No newline at end of file
diff --git a/BytecodeApi/Extensions/DateOnlyExtensions.cs b/BytecodeApi/Extensions/DateOnlyExtensions.cs
index 2b76b08..32d6342 100644
--- a/BytecodeApi/Extensions/DateOnlyExtensions.cs
+++ b/BytecodeApi/Extensions/DateOnlyExtensions.cs
@@ -318,5 +318,16 @@ public DateTime ToDateTime()
{
return dateOnly.ToDateTime(default);
}
+ ///
+ /// Returns a from this value.
+ ///
+ /// The to be used for creation of the object.
+ ///
+ /// The converted value.
+ ///
+ public DateTime ToDateTime(DateTimeKind kind)
+ {
+ return dateOnly.ToDateTime(default, kind);
+ }
}
}
\ No newline at end of file
diff --git a/BytecodeApi/Extensions/EnumerableExtensions.cs b/BytecodeApi/Extensions/EnumerableExtensions.cs
index e1c81eb..9d30ceb 100644
--- a/BytecodeApi/Extensions/EnumerableExtensions.cs
+++ b/BytecodeApi/Extensions/EnumerableExtensions.cs
@@ -1,4 +1,5 @@
using System.Collections;
+using System.ComponentModel;
namespace BytecodeApi.Extensions;
@@ -627,6 +628,118 @@ public static IEnumerable Union(this IEnumerable firs
return first.Union([second], comparer);
}
///
+ /// Sorts the elements of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// A sequence of values to sort.
+ /// Specifies the direction to sort (ascending or descending).
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedEnumerable Order(this IEnumerable source, ListSortDirection direction)
+ {
+ return source.Order(direction, null);
+ }
+ ///
+ /// Sorts the elements of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// A sequence of values to sort.
+ /// Specifies the direction to sort (ascending or descending).
+ /// An to compare the elements.
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedEnumerable Order(this IEnumerable source, ListSortDirection direction, IComparer? comparer)
+ {
+ Check.ArgumentNull(source);
+
+ return direction switch
+ {
+ ListSortDirection.Ascending => source.Order(comparer),
+ ListSortDirection.Descending => source.OrderDescending(comparer),
+ _ => throw Throw.InvalidEnumArgument(nameof(direction), direction)
+ };
+ }
+ ///
+ /// Sorts the elements of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// The type of the key returned by .
+ /// A sequence of values to sort.
+ /// A function to extract a key from an element.
+ /// Specifies the direction to sort (ascending or descending).
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, ListSortDirection direction)
+ {
+ return source.OrderBy(keySelector, direction, null);
+ }
+ ///
+ /// Sorts the elements of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// The type of the key returned by .
+ /// A sequence of values to sort.
+ /// A function to extract a key from an element.
+ /// Specifies the direction to sort (ascending or descending).
+ /// An to compare keys, or to use the default comparer.
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, ListSortDirection direction, IComparer? comparer)
+ {
+ Check.ArgumentNull(source);
+ Check.ArgumentNull(keySelector);
+
+ return direction switch
+ {
+ ListSortDirection.Ascending => source.OrderBy(keySelector, comparer),
+ ListSortDirection.Descending => source.OrderByDescending(keySelector, comparer),
+ _ => throw Throw.InvalidEnumArgument(nameof(direction), direction)
+ };
+ }
+ ///
+ /// Performs a subsequent ordering of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// The type of the key returned by .
+ /// A sequence of values to sort.
+ /// A function to extract a key from an element.
+ /// Specifies the direction to sort (ascending or descending).
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, ListSortDirection direction)
+ {
+ return source.ThenBy(keySelector, direction, null);
+ }
+ ///
+ /// Performs a subsequent ordering of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// The type of the key returned by .
+ /// A sequence of values to sort.
+ /// A function to extract a key from an element.
+ /// Specifies the direction to sort (ascending or descending).
+ /// An to compare keys, or to use the default comparer.
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, ListSortDirection direction, IComparer? comparer)
+ {
+ Check.ArgumentNull(source);
+ Check.ArgumentNull(keySelector);
+
+ return direction switch
+ {
+ ListSortDirection.Ascending => source.ThenBy(keySelector, comparer),
+ ListSortDirection.Descending => source.ThenByDescending(keySelector, comparer),
+ _ => throw Throw.InvalidEnumArgument(nameof(direction), direction)
+ };
+ }
+ ///
/// Randomizes the order of the elements of a sequence.
///
/// The type of the elements of .
@@ -634,7 +747,7 @@ public static IEnumerable Union(this IEnumerable firs
///
/// An whose elements are sorted in randomized order.
///
- public static IOrderedEnumerable SortRandom(this IEnumerable source)
+ public static IOrderedEnumerable OrderRandom(this IEnumerable source)
{
Check.ArgumentNull(source);
diff --git a/BytecodeApi/Extensions/QueryableExtensions.cs b/BytecodeApi/Extensions/QueryableExtensions.cs
new file mode 100644
index 0000000..f41465a
--- /dev/null
+++ b/BytecodeApi/Extensions/QueryableExtensions.cs
@@ -0,0 +1,57 @@
+using System.ComponentModel;
+using System.Linq.Expressions;
+
+namespace BytecodeApi.Extensions;
+
+///
+/// Provides a set of methods for interaction with objects.
+///
+public static class QueryableExtensions
+{
+ ///
+ /// Sorts the elements of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// The type of the key returned by .
+ /// A sequence of values to sort.
+ /// A function to extract a key from an element.
+ /// Specifies the direction to sort (ascending or descending).
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedQueryable OrderBy(this IQueryable source, Expression> keySelector, ListSortDirection direction)
+ {
+ Check.ArgumentNull(source);
+ Check.ArgumentNull(keySelector);
+
+ return direction switch
+ {
+ ListSortDirection.Ascending => source.OrderBy(keySelector),
+ ListSortDirection.Descending => source.OrderByDescending(keySelector),
+ _ => throw Throw.InvalidEnumArgument(nameof(direction), direction)
+ };
+ }
+ ///
+ /// Performs a subsequent ordering of a sequence in ascending or descending order, depending on the specified .
+ ///
+ /// The type of the elements of .
+ /// The type of the key returned by .
+ /// A sequence of values to sort.
+ /// A function to extract a key from an element.
+ /// Specifies the direction to sort (ascending or descending).
+ ///
+ /// An whose elements are sorted according to the specified direction.
+ ///
+ public static IOrderedQueryable ThenBy(this IOrderedQueryable source, Expression> keySelector, ListSortDirection direction)
+ {
+ Check.ArgumentNull(source);
+ Check.ArgumentNull(keySelector);
+
+ return direction switch
+ {
+ ListSortDirection.Ascending => source.ThenBy(keySelector),
+ ListSortDirection.Descending => source.ThenByDescending(keySelector),
+ _ => throw Throw.InvalidEnumArgument(nameof(direction), direction)
+ };
+ }
+}
\ No newline at end of file
diff --git a/BytecodeApi/Extensions/VersionExtensions.cs b/BytecodeApi/Extensions/VersionExtensions.cs
new file mode 100644
index 0000000..c646dd9
--- /dev/null
+++ b/BytecodeApi/Extensions/VersionExtensions.cs
@@ -0,0 +1,47 @@
+namespace BytecodeApi.Extensions;
+
+///
+/// Provides a set of methods for interaction with objects.
+///
+public static class VersionExtensions
+{
+ extension(Version version)
+ {
+ ///
+ /// Determines whether this instance is equal to another .
+ ///
+ /// The to compare to this instance.
+ /// The number of fields to compare.
+ ///
+ /// , if this instance is equal to the parameter;
+ /// otherwise, .
+ ///
+ public bool Equals(Version other, int fieldCount)
+ {
+ Check.ArgumentOutOfRange(fieldCount is >= 0 and <= 4, nameof(fieldCount), "Field count must be between 0 and 4.");
+
+ return version.CompareTo(other, fieldCount) == 0;
+ }
+ ///
+ /// Compares this instance to a specified and returns a comparison of their relative values.
+ ///
+ /// A to compare with this instance.
+ /// The number of fields to compare.
+ ///
+ /// A value that indicates the relative order of the objects being compared.
+ ///
+ public int CompareTo(Version other, int fieldCount)
+ {
+ Check.ArgumentOutOfRange(fieldCount is >= 0 and <= 4, nameof(fieldCount), "Field count must be between 0 and 4.");
+
+ int result;
+
+ if (fieldCount >= 1 && (result = version.Major.CompareTo(other.Major)) != 0) return result;
+ if (fieldCount >= 2 && (result = version.Minor.CompareTo(other.Minor)) != 0) return result;
+ if (fieldCount >= 3 && (result = version.Build.CompareTo(other.Build)) != 0) return result;
+ if (fieldCount >= 4 && (result = version.Revision.CompareTo(other.Revision)) != 0) return result;
+
+ return 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BytecodeApi/HandleableExceptionEventArgs.cs b/BytecodeApi/HandleableExceptionEventArgs.cs
new file mode 100644
index 0000000..a8f10ff
--- /dev/null
+++ b/BytecodeApi/HandleableExceptionEventArgs.cs
@@ -0,0 +1,25 @@
+using System.ComponentModel;
+
+namespace BytecodeApi;
+
+///
+/// Provides data for events that are raised when an unhandled exception occurs that can be handled by user code.
+///
+public sealed class HandleableExceptionEventArgs : HandledEventArgs
+{
+ ///
+ /// Gets the unhandled exception that was raised.
+ ///
+ public Exception Exception { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The unhandled exception that was raised.
+ public HandleableExceptionEventArgs(Exception exception)
+ {
+ Check.ArgumentNull(exception);
+
+ Exception = exception;
+ }
+}
\ No newline at end of file
diff --git a/BytecodeApi/HandleableExceptionEventHandler.cs b/BytecodeApi/HandleableExceptionEventHandler.cs
new file mode 100644
index 0000000..ef18f34
--- /dev/null
+++ b/BytecodeApi/HandleableExceptionEventHandler.cs
@@ -0,0 +1,8 @@
+namespace BytecodeApi;
+
+///
+/// Represents the method that is called when an unhandled exception occurs that can be handled by user code.
+///
+/// The object that raised the event.
+/// A that contains the event data.
+public delegate void HandleableExceptionEventHandler(object sender, HandleableExceptionEventArgs e);
\ No newline at end of file