-
Let's create a custom control that exposes two properties:
All works fine, I am able to bind both properties in the consumer Frame, and both properties are working as expected: public sealed partial class MainPage : Page
{
public MainPage() => this
.DataContext(new BindableMainPageModel(), (page, vm) => page
.Background(ThemeResource.Get<Brush>("ApplicationPageBackgroundThemeBrush"))
.Content(new StackPanel()
.VerticalAlignment(VerticalAlignment.Center)
.HorizontalAlignment(HorizontalAlignment.Center)
.Children(
new TextBlock()
.Text("Hello Uno Platform!")
.Margin(0, 0, 0, 20)
.HorizontalAlignment(HorizontalAlignment.Center),
new MyControl()
.MyValue(() => vm.MyValue)
.MyCollection(() => vm.MyCollection)
))
);
}
internal partial record MainPageModel
{
// value type property
public IState<int> MyValue => State<int>.Value(this, () => 5);
// reference type property
public IListState<object> MyCollection => ListState<object>.Value(this, () =>
[
"Model Item 1",
"Model Item 2",
"Model Item 3",
"Model Item 4",
"Model Item 5",
]);
} All good: But,
Declared type of
The content of This is not expected behavior IMO.... public sealed class MyControl : Control
{
private static readonly MyStyle _defaultStyle = new MyStyle();
public MyControl()
{
DefaultStyleKey = typeof(MyControl);
Style = _defaultStyle;
// initializing local instance of dependency property
SetValue(MyCollectionProperty, new List<object>() { "initial a", "initial b" });
}
#region MyValue
public int MyValue
{
get { return (int)GetValue(MyValueProperty); }
set { SetValue(MyValueProperty, value); }
}
public static readonly DependencyProperty MyValueProperty =
DependencyProperty.Register(
nameof(MyValue),
typeof(int),
typeof(MyControl),
new PropertyMetadata(
-1,
(s, e) => ((MyControl)s)?.OnMyValueChanged(e)));
private void OnMyValueChanged(DependencyPropertyChangedEventArgs e)
{
// Declared type of MyValue is int,
// so it is expected that the type of property and the type of e.NewValue is int
// the type should never be State<int>
//
// Current behavior is correct:
// The MyValue property is of type int, so it is e.NewValue
Debug.WriteLine($"MyValue Changed : from [{e.OldValue}] to [{e.NewValue}]");
Debug.WriteLine($"MyValue Property actual type : {this.MyValue}");
Debug.WriteLine($"NewValue actual type : {e.NewValue.GetType()}");
Debug.WriteLine("");
}
#endregion
#region MyCollection
public IEnumerable MyCollection
{
get { return (IEnumerable)GetValue(MyCollectionProperty); }
set { SetValue(MyCollectionProperty, value); }
}
public static readonly DependencyProperty MyCollectionProperty =
DependencyProperty.Register(
nameof(MyCollection),
typeof(IEnumerable),
typeof(MyControl),
new PropertyMetadata(
new List<object>() { "default" }, // initializing static instance of dependency property
(s, e) => ((MyControl)s)?.OnMyCollectionChanged(e)));
private void OnMyCollectionChanged(DependencyPropertyChangedEventArgs e)
{
// Declared type of MyCollection is IEnumerable,
// so it is expected that the type of property and the type of e.NewValue is "some" IEnumerable<object>
// the type should never be ListState<object>
//
// Current behavior is not as expected:
// The MyCollection property is of type List<int> when it is initialized from within a control, but
// it is set to IListState<object> when it comes from the MainPageModel
Debug.WriteLine($"MyCollection Changed : from [{e.OldValue}] to [{e.NewValue}]");
Debug.WriteLine($"MyCollection Property actual type : {this.MyCollection}");
Debug.WriteLine($"NewValue actual type : {e.NewValue.GetType()}");
Debug.WriteLine("");
}
#endregion
} Here you have Debug output that presents how values of
Here you have Debug output that presents how values of
You can see that Question: Is is expected behavior? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
After further investigation, I think all is ok. |
Beta Was this translation helpful? Give feedback.
After further investigation, I think all is ok.
I will think about it again, and most probably I will delete this discussion completely
Sorry for the confusion.