Skip to content

Commit

Permalink
Make bindings react to PropertyChanged even if property hasn't changed (
Browse files Browse the repository at this point in the history
#16150)

* Added failing test for #16137.

* Raise node change even if value hasn't changed.

Fixes #16137.
  • Loading branch information
grokys committed Jun 28, 2024
1 parent daaf054 commit 2ba4551
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
20 changes: 2 additions & 18 deletions src/Avalonia.Base/Data/Core/ExpressionNodes/ExpressionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,24 +211,8 @@ protected void SetValue(object? valueOrNotification)
protected void SetValue(object? value, Exception? dataValidationError = null)
{
Debug.Assert(value is not BindingNotification);

if (Owner is null)
return;

// We raise a change notification if:
//
// - This is the initial value (_value is null)
// - There is a data validation error
// - There is no data validation error, but the owner has one
// - The new value is different to the old value
if (_value is null ||
dataValidationError is not null ||
(dataValidationError is null && Owner.ErrorType == BindingErrorType.DataValidationError) ||
!Equals(value, _value))
{
_value = value;
Owner.OnNodeValueChanged(Index, value, dataValidationError);
}
_value = value;
Owner?.OnNodeValueChanged(Index, value, dataValidationError);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,26 @@ public void Can_Convert_Int_To_Enum_Two_Way()
GC.KeepAlive(data);
}

[Fact]
public void Converter_Should_Be_Called_On_PropertyChanged_Even_If_Property_Not_Changed()
{
// Issue #16137
var data = new ViewModel();
var converter = new PrefixConverter("foo");
var target = CreateTargetWithSource(
data,
o => o.IntValue,
converter: converter,
targetProperty: TargetClass.StringProperty);

Assert.Equal("foo0", target.String);

converter.Prefix = "bar";
data.RaisePropertyChanged(nameof(data.IntValue));

Assert.Equal("bar0", target.String);
}

private class DerivedViewModel : ViewModel
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,14 +417,20 @@ BindingValueType b when b.HasFlag(BindingValueType.DataValidationError) => Bindi

protected class PrefixConverter : IValueConverter
{
public PrefixConverter(string? prefix = null) => Prefix = prefix;

public string? Prefix { get; set; }

public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (targetType != typeof(string))
return value;

var result = value?.ToString() ?? string.Empty;
if (parameter is not null)
result = parameter.ToString() + result;
var prefix = parameter?.ToString() ?? Prefix;

if (prefix is not null)
result = prefix + result;
return result;
}

Expand Down

0 comments on commit 2ba4551

Please sign in to comment.