Updating a bound object with INotifyPropertyChanged does not work
Posted: 06 Sep 2023, 12:24
Hi,
I'm having trouble when updating the UI that is bound to an scriptable object.
I simplified my example extremely, so it can be understood easier. I hope that I managed to catch the essence of it.
I have a UserControl called "MilestoneViewComponent". It expects an object of my PlayerData (ScriptableObject) class and displays some of its attribtues.
This UserControl is being used in the Main View, where I have a binding to my PlayerData.
My Observation:
I have a script that holds my PlayerDataObject and implements INotifyPropertyChanged.
When I call INotifyPropertyChanged on "PlayerData" my view does not update.
I added a float variable called "Money".
When I call INotifyPropertyChanged on "Money" my view does update.
Question:
Is it possible that you can't pass objects as a binding and still call updates on them when only data inside the object has changed?
Here is my Main View xaml:
This is my code behind of the MilestoneViewComponent:
I hope that I did not simplify my issue too much. I'm happy to add some more information if needed.
Thanks in advance,
David
I'm having trouble when updating the UI that is bound to an scriptable object.
I simplified my example extremely, so it can be understood easier. I hope that I managed to catch the essence of it.
I have a UserControl called "MilestoneViewComponent". It expects an object of my PlayerData (ScriptableObject) class and displays some of its attribtues.
This UserControl is being used in the Main View, where I have a binding to my PlayerData.
My Observation:
I have a script that holds my PlayerDataObject and implements INotifyPropertyChanged.
When I call INotifyPropertyChanged on "PlayerData" my view does not update.
I added a float variable called "Money".
When I call INotifyPropertyChanged on "Money" my view does update.
Question:
Is it possible that you can't pass objects as a binding and still call updates on them when only data inside the object has changed?
Here is my Main View xaml:
Code: Select all
<UserControl x:Class="Testing.GameView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
Focusable="True"
x:Name="Root">
<Grid x:Name="RootGrid">
<local:MilestoneViewComponent PlayerData="{Binding PlayerData, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Money="{Binding CurrentMoney, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</UserControl>
Code: Select all
public partial class MilestoneViewComponent : UserControl, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public PlayerDataSO PlayerData {
get { return (PlayerDataSO) GetValue(PlayerDataProperty); }
set { SetValue(PlayerDataProperty, value); }
}
public static void OnPlayerDataChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
MilestoneViewComponent milestoneViewComponent = sender as MilestoneViewComponent;
//Here some of my other bindings are updated that are read from the player
milestoneViewComponent.OnPropertyChanged(nameof(PlayerName));
/*
This is not getting called when I update the PlayerData
*/
}
public static readonly DependencyProperty PlayerDataProperty = DependencyProperty.Register(
nameof(PlayerData), typeof(PlayerDataSO), typeof(MilestoneViewComponent), new PropertyMetadata(null, new PropertyChangedCallback(OnPlayerDataChanged)));
public Float Money {
get { return (Float) GetValue(MoneyProperty); }
set { SetValue(MoneyProperty, value); }
}
public static void OnMoneyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
MilestoneViewComponent milestoneViewComponent = sender as MilestoneViewComponent;
//Here some of my other bindings are updated that are read from the player
milestoneViewComponent.OnPropertyChanged(nameof(PlayerName));
/*
This is getting called when I update Money
*/
}
public static readonly DependencyProperty MoneyProperty = DependencyProperty.Register(
nameof(Money), typeof(Float), typeof(MilestoneViewComponent), new PropertyMetadata((Float) 0, new PropertyChangedCallback(OnMoneyChanged)));
}
Thanks in advance,
David