I have tried to isolate my problem in a very simple (and working) project. Let's say I have a simple model with 2 fields, and I have configured its properties and a PropertyChanged
event. This is a simplified implementation of my model, please notice the last method just gets a new client object from a list and returns it:
public class Clients : INotifyPropertyChanged
{
private long _Id = 0;
public long Id
{
get { return this._Id; }
set {
this._Id = value;
RaisePropertyChanged("Id");
}
}
private String _Name = string.Empty;
public String Name
{
get { return this._Name; }
set {
if (value is null)
this._Name = string.Empty;
else
this._Name = value;
RaisePropertyChanged("Name");
}
}
public event PropertyChangedEventHandler? PropertyChanged;
internal void RaisePropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
// Let's say this is a populated list with 100 clients with different ids and names
public static List<Clients> clients = new List<Clients>();
// ...method for loading the list with DB data
public static Clients? LoadClient(long id)
{
return clients.FirstOrDefault(x => x.Id == id);
}
}
And I have a simple .xaml
file in order to display one client data (id and name). Each UI control has a binding with the client property and the trigger for updating. I have also 2 configured buttons that will make changes to the client values:
<TextBox x:Name="txtClientId" Text="{Binding Id, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
<TextBox x:Name="txtClientName" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
<Button Name="btnNext" Click="btnNext_Click">Next</Button>
<Button Name="btnRandom" Click="btnRandom_Click">Random</Button>
Now let's take a look to my .xaml.cs
code. Here is the initializing and the code for the 2 buttons: one of them just modify the client properties in the DataContext
object directly, and the other just assigns a new client object to the DataContext
client:
public partial class ClientsPage : Page
{
private Models.Clients? client = null;
public ClientsPage()
{
InitializeComponent();
// Load all clients data in Models.Clients.clients list...
client = new Models.Clients();
DataContext = client;
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
client = Models.Clients.LoadClient(client.Id + 1);
}
private void btnRandom_Click(object sender, RoutedEventArgs e)
{
Random random = new Random();
client.Id = random.Next(999);
client.Name = "RANDOM";
}
}
DataContext
, UI doesn't change since the PropertyChanged
event is not raised.Of course this situation can be solved by assigning property values instead of assigning a new object directly:
private void btnNext_Click(object sender, RoutedEventArgs e)
{
Models.Clients newClient = Models.Clients.LoadClient(client.Id + 1);
this.client.Id = newClient.Id;
this.client.Name = newClient.Name;
}
But it is so tedious in a real project with many models and methods that can load/modify an object with a lot of fields. I'm looking for an easy/scalable way for making the PropertyChanged
event fire when I assign a new object to the DataContext
variable. If you need more detail of my code or have any question I'll be happy to ask.
The new instance of the object is created but has not been assigned to DataContext. Assignment to DataContext is required. Correct code is :
private void btnNext_Click(object sender, RoutedEventArgs e)
{
client = Models.Clients.LoadClient(client.Id + 1);
DataContext = client;
}