-
Notifications
You must be signed in to change notification settings - Fork 717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DP set explicitly to default value does not raise dp-changed event #11448
Comments
Very curious behavior, thanks for the issue! |
Is it for enums specifically? Is WinUI here comparing the boxed value by reference? |
public sealed partial class MyPage : Page
{
public MyPage()
{
Debug.WriteLine("Changing IntegerProperty");
IntegerProperty = 0;
Debug.WriteLine("Changing EnumProperty");
EnumProperty = 0;
Debug.WriteLine("Changing EnumProperty");
EnumProperty = 0;
Debug.WriteLine("Changing EnumProperty");
EnumProperty = 0;
Debug.WriteLine("Changing EnumProperty");
EnumProperty = 0;
}
public int IntegerProperty
{
get { return (int)GetValue(IntegerPropertyProperty); }
set { SetValue(IntegerPropertyProperty, value); }
}
public static DependencyProperty IntegerPropertyProperty { get; } =
DependencyProperty.Register(nameof(IntegerProperty), typeof(int), typeof(MyPage), new PropertyMetadata(0, propertyChangedCallback: OnIntegerChanged));
private static void OnIntegerChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
Debug.WriteLine(nameof(OnIntegerChanged));
}
public E EnumProperty
{
get { return (E)GetValue(EnumPropertyProperty); }
set { SetValue(EnumPropertyProperty, value); }
}
public static DependencyProperty EnumPropertyProperty { get; } =
DependencyProperty.Register(nameof(EnumProperty), typeof(int), typeof(MyPage), new PropertyMetadata((E)0, propertyChangedCallback: OnEnumChanged));
private static void OnEnumChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
Debug.WriteLine(nameof(OnEnumChanged));
}
} Produces:
However, Debug.WriteLine("Changing IntegerProperty");
IntegerProperty = 0;
object boxed = (E)0;
Debug.WriteLine("Changing EnumProperty");
SetValue(EnumPropertyProperty, boxed);
Debug.WriteLine("Changing EnumProperty");
SetValue(EnumPropertyProperty, boxed);
Debug.WriteLine("Changing EnumProperty");
SetValue(EnumPropertyProperty, boxed);
Debug.WriteLine("Changing EnumProperty");
SetValue(EnumPropertyProperty, boxed); produces: Changing IntegerProperty
Changing EnumProperty
OnEnumChanged
Changing EnumProperty
Changing EnumProperty
Changing EnumProperty So, for enums, we should be using reference equality to match WinUI. But I don't see why are enums so special here. So need to understand this more. It also feels like a WinUI bug actually 😕 |
@Xiaoy312 I'm curious why this caused a trouble for you? Code shouldn't be relying on this weird behavior I think. |
template<typename CValueType>
_Check_return_ HRESULT TryUnboxPropertyValue(
_In_ wf::IPropertyValue* inValue,
_Out_ CValueType& outValue,
_Out_ bool& success)
{
// Quick and dirty way to convert the most common types to a CValue.
ASSERT(inValue);
success = false;
wf::PropertyType ePropertyType = wf::PropertyType::PropertyType_Empty;
IFC_RETURN(inValue->get_Type(&ePropertyType));
switch (ePropertyType)
{
case wf::PropertyType_Boolean:
{
BOOLEAN bValue = FALSE;
IFC_RETURN(inValue->GetBoolean(&bValue));
outValue.SetBool(!!bValue);
}
break;
case wf::PropertyType_Int32:
{
INT32 nValue = 0;
IFC_RETURN(inValue->GetInt32(&nValue));
outValue.SetSigned(nValue);
}
break;
case wf::PropertyType_UInt32:
{
// TODO: We need to introduce valueUnsigned for correctness.
UINT32 nValue = 0;
IFC_RETURN(inValue->GetUInt32(&nValue));
outValue.SetSigned((INT32)nValue);
}
break;
case wf::PropertyType_Int64:
{
INT64 value = 0;
IFC_RETURN(inValue->GetInt64(&value));
outValue.SetInt64(value);
}
break;
case wf::PropertyType_UInt64:
{
UINT64 value = 0;
IFC_RETURN(inValue->GetUInt64(&value));
outValue.SetInt64(static_cast<INT64>(value));
}
break;
case wf::PropertyType_Double:
{
DOUBLE nValue = 0.0;
IFC_RETURN(inValue->GetDouble(&nValue));
outValue.SetDouble(nValue);
}
break;
case wf::PropertyType_Single:
{
FLOAT nValue = 0.0f;
IFC_RETURN(inValue->GetSingle(&nValue));
outValue.SetFloat(nValue);
}
break;
case wf::PropertyType_String:
{
wrl_wrappers::HString str;
IFC_RETURN(inValue->GetString(str.GetAddressOf()));
IFC_RETURN(outValue.SetString(str.Get()));
}
break;
case wf::PropertyType_TimeSpan:
{
wf::TimeSpan timeSpan = {};
IFC_RETURN(inValue->GetTimeSpan(&timeSpan));
outValue.SetTimeSpan(timeSpan);
}
break;
case wf::PropertyType_DateTime:
{
wf::DateTime dateTime = {};
IFC_RETURN(inValue->GetDateTime(&dateTime));
outValue.SetDateTime(dateTime);
}
break;
case wf::PropertyType_OtherType:
// We don't have a good way to compare custom structs.
// early exit without setting success to true
return S_OK;
default:
// NOTE: If there are other commonly used types, consider supporting those here for a small CPU improvement
// when doing a check to see if a property value changed.
// early exit without setting success to true
return S_OK;
}
success = true;
return S_OK;
} |
@jeromelaban @Xiaoy312 I'm not sure if this is something we should match or not. |
It is not something of priority, since I found the (Enum)0 workaround. |
@Xiaoy312 To me, it feels like a WinUI bug actually. Initialization code shouldn't be relying on "incorrect" DP changed callback IMO. |
fair enough |
Current behavior
With a
DependencyProperty
whose default value is set to an enum value, trying to set this dp value to the same initial value does not trigger thePropertyChangedCallback
.Expected behavior
^ it should trigger
How to reproduce it (as minimally and precisely as possible)
relevant source
repro sample: Toolkit451RelatedIssues.zip
repro steps:
^ this does not happen with uno
Workaround
using
(Asd)0
as default value, and then set it asAsd.A
.Works on UWP/WinUI
Yes
Environment
Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia
NuGet package version(s)
Uno.UI@4.7.30
Affected platforms
Android, iOS, Skia (GTK on Linux/macOS/Windows)
IDE
Visual Studio 2022
IDE version
No response
Relevant plugins
No response
Anything else we need to know?
No response
The text was updated successfully, but these errors were encountered: