diff --git a/src/AtomUI.Controls.DataGrid/DataGridRowGroupHeader.cs b/src/AtomUI.Controls.DataGrid/DataGridRowGroupHeader.cs new file mode 100644 index 000000000..dc39749fd --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/DataGridRowGroupHeader.cs @@ -0,0 +1,8 @@ +using Avalonia.Controls.Primitives; + +namespace AtomUI.Controls; + +public class DataGridRowGroupHeader : TemplatedControl +{ + +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridAutoGeneratingColumnEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridAutoGeneratingColumnEventArgs.cs new file mode 100644 index 000000000..31907527b --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridAutoGeneratingColumnEventArgs.cs @@ -0,0 +1,57 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.ComponentModel; + +namespace AtomUI.Controls; + +public class DataGridAutoGeneratingColumnEventArgs : CancelEventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// + /// The name of the property bound to the generated column. + /// + /// + /// The of the property bound to the generated column. + /// + /// + /// The generated column. + /// + public DataGridAutoGeneratingColumnEventArgs(string propertyName, Type propertyType, DataGridColumn column) + { + Column = column; + PropertyName = propertyName; + PropertyType = propertyType; + } + + /// + /// Gets the generated column. + /// + public DataGridColumn Column + { + get; + set; + } + + /// + /// Gets the name of the property bound to the generated column. + /// + public string PropertyName + { + get; + private set; + } + + /// + /// Gets the of the property bound to the generated column. + /// + public Type PropertyType + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridBeginningEditEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridBeginningEditEventArgs.cs new file mode 100644 index 000000000..64ebf6bdc --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridBeginningEditEventArgs.cs @@ -0,0 +1,62 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.ComponentModel; +using Avalonia.Interactivity; + +namespace AtomUI.Controls; + +public class DataGridBeginningEditEventArgs: CancelEventArgs +{ + /// + /// Initializes a new instance of the + /// class. + /// + /// + /// The column that contains the cell to be edited. + /// + /// + /// The row that contains the cell to be edited. + /// + /// + /// Information about the user gesture that caused the cell to enter edit mode. + /// + public DataGridBeginningEditEventArgs(DataGridColumn column, + DataGridRow row, + RoutedEventArgs editingEventArgs) + { + Column = column; + Row = row; + EditingEventArgs = editingEventArgs; + } + + /// + /// Gets the column that contains the cell to be edited. + /// + public DataGridColumn Column + { + get; + private set; + } + + /// + /// Gets information about the user gesture that caused the cell to enter edit mode. + /// + public RoutedEventArgs EditingEventArgs + { + get; + private set; + } + + /// + /// Gets the row that contains the cell to be edited. + /// + public DataGridRow Row + { + get; + private set; + } + +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEditEndedEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEditEndedEventArgs.cs new file mode 100644 index 000000000..3b97a7a17 --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEditEndedEventArgs.cs @@ -0,0 +1,50 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +namespace AtomUI.Controls; + +public class DataGridCellEditEndedEventArgs : System.EventArgs +{ + /// + /// Instantiates a new instance of this class. + /// + /// The column of the cell that has just exited edit mode. + /// The row container of the cell container that has just exited edit mode. + /// The editing action that has been taken. + public DataGridCellEditEndedEventArgs(DataGridColumn column, DataGridRow row, DataGridEditAction editAction) + { + Column = column; + Row = row; + EditAction = editAction; + } + + /// + /// The column of the cell that has just exited edit mode. + /// + public DataGridColumn Column + { + get; + private set; + } + + /// + /// The edit action taken when leaving edit mode. + /// + public DataGridEditAction EditAction + { + get; + private set; + } + + /// + /// The row container of the cell container that has just exited edit mode. + /// + public DataGridRow Row + { + get; + private set; + } + +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEditEndingEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEditEndingEventArgs.cs new file mode 100644 index 000000000..4a2499fe0 --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEditEndingEventArgs.cs @@ -0,0 +1,67 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.ComponentModel; +using Avalonia.Controls; + +namespace AtomUI.Controls; + +public class DataGridCellEditEndingEventArgs : CancelEventArgs +{ + /// + /// Instantiates a new instance of this class. + /// + /// The column of the cell that is about to exit edit mode. + /// The row container of the cell container that is about to exit edit mode. + /// The editing element within the cell. + /// The editing action that will be taken. + public DataGridCellEditEndingEventArgs(DataGridColumn column, + DataGridRow row, + Control editingElement, + DataGridEditAction editAction) + { + Column = column; + Row = row; + EditingElement = editingElement; + EditAction = editAction; + } + + /// + /// The column of the cell that is about to exit edit mode. + /// + public DataGridColumn Column + { + get; + private set; + } + + /// + /// The edit action to take when leaving edit mode. + /// + public DataGridEditAction EditAction + { + get; + private set; + } + + /// + /// The editing element within the cell. + /// + public Control EditingElement + { + get; + private set; + } + + /// + /// The row container of the cell container that is about to exit edit mode. + /// + public DataGridRow Row + { + get; + private set; + } + +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEventArgs.cs new file mode 100644 index 000000000..414b2aa1f --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellEventArgs.cs @@ -0,0 +1,23 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.Diagnostics; + +namespace AtomUI.Controls; + +public class DataGridCellEventArgs : EventArgs +{ + internal DataGridCellEventArgs(DataGridCell dataGridCell) + { + Debug.Assert(dataGridCell != null); + Cell = dataGridCell; + } + + internal DataGridCell Cell + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellPointerPressedEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellPointerPressedEventArgs.cs new file mode 100644 index 000000000..8fe04240d --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridCellPointerPressedEventArgs.cs @@ -0,0 +1,49 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using Avalonia.Input; + +namespace AtomUI.Controls; + +public class DataGridCellPointerPressedEventArgs : EventArgs +{ + /// + /// Instantiates a new instance of this class. + /// + /// The cell that has been pressed. + /// The row container of the cell that has been pressed. + /// The column of the cell that has been pressed. + /// The pointer action that has been taken. + public DataGridCellPointerPressedEventArgs(DataGridCell cell, + DataGridRow row, + DataGridColumn column, + PointerPressedEventArgs e) + { + Cell = cell; + Row = row; + Column = column; + PointerPressedEventArgs = e; + } + + /// + /// The cell that has been pressed. + /// + public DataGridCell Cell { get; } + + /// + /// The row container of the cell that has been pressed. + /// + public DataGridRow Row { get; } + + /// + /// The column of the cell that has been pressed. + /// + public DataGridColumn Column { get; } + + /// + /// The pointer action that has been taken. + /// + public PointerPressedEventArgs PointerPressedEventArgs { get; } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridColumnEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridColumnEventArgs.cs new file mode 100644 index 000000000..b1ac9d383 --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridColumnEventArgs.cs @@ -0,0 +1,29 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.ComponentModel; + +namespace AtomUI.Controls; + +public class DataGridColumnEventArgs : HandledEventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// The column that the event occurs for. + public DataGridColumnEventArgs(DataGridColumn column) + { + Column = column ?? throw new ArgumentNullException(nameof(column)); + } + + /// + /// Gets the column that the event occurs for. + /// + public DataGridColumn Column + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridColumnReorderingEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridColumnReorderingEventArgs.cs new file mode 100644 index 000000000..9cc23003a --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridColumnReorderingEventArgs.cs @@ -0,0 +1,48 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.ComponentModel; +using Avalonia.Controls; + +namespace AtomUI.Controls; + +public class DataGridColumnReorderingEventArgs : CancelEventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// + public DataGridColumnReorderingEventArgs(DataGridColumn dataGridColumn) + { + Column = dataGridColumn; + } + + /// + /// The column being moved. + /// + public DataGridColumn Column + { + get; + private set; + } + + /// + /// The popup indicator displayed while dragging. If null and Handled = true, then do not display a tooltip. + /// + public Control? DragIndicator + { + get; + set; + } + + /// + /// UIElement to display at the insertion position. If null and Handled = true, then do not display an insertion indicator. + /// + public Control? DropLocationIndicator + { + get; + set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridPreparingCellForEditEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridPreparingCellForEditEventArgs.cs new file mode 100644 index 000000000..d5d5f68d4 --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridPreparingCellForEditEventArgs.cs @@ -0,0 +1,67 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using Avalonia.Controls; +using Avalonia.Interactivity; + +namespace AtomUI.Controls; + +public class DataGridPreparingCellForEditEventArgs: EventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// The column that contains the cell to be edited. + /// The row that contains the cell to be edited. + /// Information about the user gesture that caused the cell to enter edit mode. + /// The element that the column displays for a cell in editing mode. + public DataGridPreparingCellForEditEventArgs(DataGridColumn column, + DataGridRow row, + RoutedEventArgs editingEventArgs, + Control editingElement) + { + Column = column; + Row = row; + EditingEventArgs = editingEventArgs; + EditingElement = editingElement; + } + + /// + /// Gets the column that contains the cell to be edited. + /// + public DataGridColumn Column + { + get; + private set; + } + + /// + /// Gets the element that the column displays for a cell in editing mode. + /// + public Control EditingElement + { + get; + private set; + } + + /// + /// Gets information about the user gesture that caused the cell to enter edit mode. + /// + public RoutedEventArgs EditingEventArgs + { + get; + private set; + } + + /// + /// Gets the row that contains the cell to be edited. + /// + public DataGridRow Row + { + get; + private set; + } + +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowDetailsEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowDetailsEventArgs.cs new file mode 100644 index 000000000..f1dce88cf --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowDetailsEventArgs.cs @@ -0,0 +1,40 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using Avalonia.Controls; + +namespace AtomUI.Controls; + +public class DataGridRowDetailsEventArgs : EventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// The row that the event occurs for. + /// The row details section as a framework element. + public DataGridRowDetailsEventArgs(DataGridRow row, Control detailsElement) + { + Row = row; + DetailsElement = detailsElement; + } + + /// + /// Gets the row details section as a framework element. + /// + public Control DetailsElement + { + get; + private set; + } + + /// + /// Gets the row that the event occurs for. + /// + public DataGridRow Row + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEditEndedEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEditEndedEventArgs.cs new file mode 100644 index 000000000..d1db8d72b --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEditEndedEventArgs.cs @@ -0,0 +1,38 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +namespace AtomUI.Controls; + +public class DataGridRowEditEndedEventArgs : EventArgs +{ + /// + /// Instantiates a new instance of this class. + /// + /// The row container of the cell container that has just exited edit mode. + /// The editing action that has been taken. + public DataGridRowEditEndedEventArgs(DataGridRow row, DataGridEditAction editAction) + { + Row = row; + EditAction = editAction; + } + + /// + /// The editing action that has been taken. + /// + public DataGridEditAction EditAction + { + get; + private set; + } + + /// + /// The row container of the cell container that has just exited edit mode. + /// + public DataGridRow Row + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEditEndingEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEditEndingEventArgs.cs new file mode 100644 index 000000000..05c4c9d3e --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEditEndingEventArgs.cs @@ -0,0 +1,40 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.ComponentModel; + +namespace AtomUI.Controls; + +public class DataGridRowEditEndingEventArgs : CancelEventArgs +{ + /// + /// Instantiates a new instance of this class. + /// + /// The row container of the cell container that is about to exit edit mode. + /// The editing action that will be taken. + public DataGridRowEditEndingEventArgs(DataGridRow row, DataGridEditAction editAction) + { + Row = row; + EditAction = editAction; + } + + /// + /// The editing action that will be taken. + /// + public DataGridEditAction EditAction + { + get; + private set; + } + + /// + /// The row container of the cell container that is about to exit edit mode. + /// + public DataGridRow Row + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEventArgs.cs new file mode 100644 index 000000000..7b9b6281c --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowEventArgs.cs @@ -0,0 +1,27 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +namespace AtomUI.Controls; + +public class DataGridRowEventArgs : EventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// The row that the event occurs for. + public DataGridRowEventArgs(DataGridRow dataGridRow) + { + Row = dataGridRow; + } + + /// + /// Gets the row that the event occurs for. + /// + public DataGridRow Row + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowGroupHeaderEventArgs.cs b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowGroupHeaderEventArgs.cs new file mode 100644 index 000000000..6b92dd36d --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/EventArgs/DataGridRowGroupHeaderEventArgs.cs @@ -0,0 +1,27 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +namespace AtomUI.Controls; + +public class DataGridRowGroupHeaderEventArgs : EventArgs +{ + /// + /// Constructs a DataGridRowGroupHeaderEventArgs instance + /// + /// + public DataGridRowGroupHeaderEventArgs(DataGridRowGroupHeader rowGroupHeader) + { + RowGroupHeader = rowGroupHeader; + } + + /// + /// DataGridRowGroupHeader associated with this instance + /// + public DataGridRowGroupHeader RowGroupHeader + { + get; + private set; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls.DataGrid/Utils/ValidationUtils.cs b/src/AtomUI.Controls.DataGrid/Utils/ValidationUtils.cs new file mode 100644 index 000000000..956d4e1cc --- /dev/null +++ b/src/AtomUI.Controls.DataGrid/Utils/ValidationUtils.cs @@ -0,0 +1,161 @@ +using System.ComponentModel.DataAnnotations; +using Avalonia.Data; + +namespace AtomUI.Controls.Utils; + +internal static class ValidationUtils +{ + /// + /// Searches a ValidationResult for the specified target member name. If the target is null + /// or empty, this method will return true if there are no member names at all. + /// + /// ValidationResult to search. + /// Member name to search for. + /// True if found. + public static bool ContainsMemberName(this ValidationResult validationResult, string target) + { + int memberNameCount = 0; + foreach (string memberName in validationResult.MemberNames) + { + if (string.Equals(target, memberName)) + { + return true; + } + memberNameCount++; + } + return (memberNameCount == 0 && string.IsNullOrEmpty(target)); + } + + /// + /// Finds an equivalent ValidationResult if one exists. + /// + /// ValidationResults to search through. + /// ValidationResult to find. + /// Equal ValidationResult if found, null otherwise. + public static ValidationResult? FindEqualValidationResult(this ICollection collection, ValidationResult target) + { + foreach (ValidationResult oldValidationResult in collection) + { + if (oldValidationResult.ErrorMessage == target.ErrorMessage) + { + bool movedOld = true; + bool movedTarget = true; + IEnumerator oldEnumerator = oldValidationResult.MemberNames.GetEnumerator(); + IEnumerator targetEnumerator = target.MemberNames.GetEnumerator(); + while (movedOld && movedTarget) + { + movedOld = oldEnumerator.MoveNext(); + movedTarget = targetEnumerator.MoveNext(); + + if (!movedOld && !movedTarget) + { + return oldValidationResult; + } + if (movedOld != movedTarget || oldEnumerator.Current != targetEnumerator.Current) + { + break; + } + } + } + } + return null; + } + + public static bool IsValid(this ValidationResult? result) + { + return result == null || result == ValidationResult.Success; + } + + public static IEnumerable UnpackException(Exception? exception) + { + if (exception != null) + { + var exceptions = exception is AggregateException aggregate ? + aggregate.InnerExceptions : + (IEnumerable)new[] { exception }; + + return exceptions.Where(x => !(x is BindingChainException)).ToList(); + } + + return Array.Empty(); + } + + public static object? UnpackDataValidationException(Exception? exception) + { + if (exception is DataValidationException dataValidationException) + { + return dataValidationException.ErrorData; + } + + return exception; + } + + /// + /// Determines whether the collection contains an equivalent ValidationResult + /// + /// ValidationResults to search through + /// ValidationResult to search for + /// + public static bool ContainsEqualValidationResult(this ICollection collection, ValidationResult target) + { + return collection.FindEqualValidationResult(target) != null; + } + + /// + /// Adds a new ValidationResult to the collection if an equivalent does not exist. + /// + /// ValidationResults to search through + /// ValidationResult to add + public static void AddIfNew(this ICollection collection, ValidationResult value) + { + if (!collection.ContainsEqualValidationResult(value)) + { + collection.Add(value); + } + } + + private static bool ExceptionsMatch(Exception e1, Exception e2) + { + return e1.Message == e2.Message; + } + public static void AddExceptionIfNew(this ICollection collection, Exception value) + { + if(!collection.Any(e => ExceptionsMatch(e, value))) + { + collection.Add(value); + } + } + + /// + /// Performs an action and catches any non-critical exceptions. + /// + /// Action to perform + public static void CatchNonCriticalExceptions(Action action) + { + try + { + action(); + } + catch (Exception exception) + { + if (IsCriticalException(exception)) + { + throw; + } + // Catch any non-critical exceptions + } + } + + /// + /// Determines if the specified exception is un-recoverable. + /// + /// The exception. + /// True if the process cannot be recovered from the exception. + public static bool IsCriticalException(Exception exception) + { + return (exception is OutOfMemoryException) || + (exception is StackOverflowException) || + (exception is AccessViolationException) || + (exception is ThreadAbortException); + } +} \ No newline at end of file