feat: Handle Datavalidations on base class "Control" (#20067)

* Handle Datavalidations on base class "Control"

this removes the need to override it in any sub-classing control and also allowes developers to add validation support for other properties / controls by overriding Metadata

* Revert changes on Button.

The current behavior is that button gets disabled and until we decide if this is desired, keep this behavior.
This commit is contained in:
Tim
2025-11-26 18:03:14 +01:00
committed by GitHub
parent d2817201cb
commit 55a0b5b1c6
11 changed files with 11 additions and 105 deletions
@@ -652,24 +652,6 @@ namespace Avalonia.Controls
base.OnApplyTemplate(e);
}
/// <summary>
/// Called to update the validation state for properties for which data validation is
/// enabled.
/// </summary>
/// <param name="property">The property.</param>
/// <param name="state">The current data binding state.</param>
/// <param name="error">The current data binding error, if any.</param>
protected override void UpdateDataValidation(
AvaloniaProperty property,
BindingValueType state,
Exception? error)
{
if (property == TextProperty || property == SelectedItemProperty)
{
DataValidationErrors.SetError(this, error);
}
}
/// <summary>
/// Provides handling for the
/// <see cref="E:Avalonia.InputElement.KeyDown" /> event.
+2 -1
View File
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Windows.Input;
using Avalonia.Automation.Peers;
@@ -571,7 +572,7 @@ namespace Avalonia.Controls
}
}
}
internal void PerformClick() => OnClick();
private static void OnAccessKeyPressed(Button sender, AccessKeyPressedEventArgs e)
@@ -325,17 +325,6 @@ namespace Avalonia.Controls
base.OnPropertyChanged(change);
}
/// <inheritdoc/>
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValueType state, Exception? error)
{
if (property == SelectedDateProperty)
{
DataValidationErrors.SetError(this, error);
}
base.UpdateDataValidation(property, state, error);
}
/// <inheritdoc/>
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
+8
View File
@@ -4,6 +4,7 @@ using System.ComponentModel;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Interactivity;
@@ -563,6 +564,13 @@ namespace Avalonia.Controls
}
}
}
/// <inheritdoc />
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValueType state, Exception? error)
{
DataValidationErrors.SetError(this, error);
base.UpdateDataValidation(property, state, error);
}
// Since we are resetting the dispatcher instance, the callback might never arrive
internal static void ResetLoadedQueueForUnitTests()
@@ -426,13 +426,5 @@ namespace Avalonia.Controls
{
SetCurrentValue(SelectedDateProperty, null);
}
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValueType state, Exception? error)
{
base.UpdateDataValidation(property, state, error);
if (property == SelectedDateProperty)
DataValidationErrors.SetError(this, error);
}
}
}
@@ -407,13 +407,5 @@ namespace Avalonia.Controls
{
SetCurrentValue(SelectedTimeProperty, null);
}
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValueType state, Exception? error)
{
base.UpdateDataValidation(property, state, error);
if (property == SelectedTimeProperty)
DataValidationErrors.SetError(this, error);
}
}
}
+1
View File
@@ -554,6 +554,7 @@ namespace Avalonia.Controls
return new MenuItemAutomationPeer(this);
}
// TODO: This is confusing for some ppl. Need to think about alternatives here.
protected override void UpdateDataValidation(
AvaloniaProperty property,
BindingValueType state,
@@ -441,24 +441,6 @@ namespace Avalonia.Controls
}
}
/// <summary>
/// Called to update the validation state for properties for which data validation is
/// enabled.
/// </summary>
/// <param name="property">The property.</param>
/// <param name="state">The current data binding state.</param>
/// <param name="error">The current data binding error, if any.</param>
protected override void UpdateDataValidation(
AvaloniaProperty property,
BindingValueType state,
Exception? error)
{
if (property == TextProperty || property == ValueProperty)
{
DataValidationErrors.SetError(this, error);
}
}
/// <summary>
/// Called when the <see cref="NumberFormat"/> property value changed.
/// </summary>
@@ -569,24 +569,6 @@ namespace Avalonia.Controls.Primitives
EndUpdating();
}
/// <summary>
/// Called to update the validation state for properties for which data validation is
/// enabled.
/// </summary>
/// <param name="property">The property.</param>
/// <param name="state">The current data binding state.</param>
/// <param name="error">The current data binding error, if any.</param>
protected override void UpdateDataValidation(
AvaloniaProperty property,
BindingValueType state,
Exception? error)
{
if (property == SelectedItemProperty)
{
DataValidationErrors.SetError(this, error);
}
}
/// <inheritdoc />
protected override void OnInitialized()
{
-12
View File
@@ -393,18 +393,6 @@ namespace Avalonia.Controls
SetCurrentValue(ValueProperty, IsSnapToTickEnabled ? SnapToTick(finalValue) : finalValue);
}
/// <inheritdoc />
protected override void UpdateDataValidation(
AvaloniaProperty property,
BindingValueType state,
Exception? error)
{
if (property == ValueProperty)
{
DataValidationErrors.SetError(this, error);
}
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new SliderAutomationPeer(this);
-11
View File
@@ -1884,17 +1884,6 @@ namespace Avalonia.Controls
return new TextBoxAutomationPeer(this);
}
protected override void UpdateDataValidation(
AvaloniaProperty property,
BindingValueType state,
Exception? error)
{
if (property == TextProperty)
{
DataValidationErrors.SetError(this, error);
}
}
internal static int CoerceCaretIndex(AvaloniaObject sender, int value)
{
var text = sender.GetValue(TextProperty); // method also used by TextPresenter and SelectableTextBlock