Thanks. I hope I could upload the whole solution for I have prepared one before open this question. but I didn't find how. I will copy all the code as posible as I can here.
The question is: I think this is an easy replicated issue within WPF. I made a simple version of code to explain my question clearly. The container 'TwoPersons' in the sample has two instances of class 'Person'. The 'Current' property will be data context of a detail panel which populates person's detail info. I can use Current setter method to jump between different persions. I can see the details changing accordingly. The question is during the switching and populating current person, UI controls changes (like change male to female), then the change affects PREVIOUS item it was binding. The persion instance will be modified unexpectly. It seems previous instance still has connection with the view after new instance bound. How can I avoid this situation. Any help will be appreciated.
========================================================================
This is MainWindow.xaml.cs
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
TwoPersons twoPersons = new TwoPersons();
public MainWindow()
{
InitializeComponent();
DataContext = twoPersons;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
twoPersons.Next();
}
}
The container with two persons:
public class TwoPersons : INotifyPropertyChanged
{
Person p1 = new Person("Mary") { IsFemale = true };
Person p2 = new Person("Luis") { IsMale = true };
Person current;
public Person Current
{
get
{
if (current == null)
current = p1;
return current;
}
set
{
if (current != value)
{
current = value;
OnPropertyChanged("Current");
}
}
}
public void Next()
{
Current = Current == p1 ? p2 : p1;
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
PropertyChanged(this, e);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
The person class:
public class Person : INotifyPropertyChanged
{
public Person(string name)
{
this.name = name;
}
private string name;
public string Name
{
get { return name; }
}
public bool isMale;
public bool IsMale
{
get { return isMale; }
set
{
if (isMale != value)
{
isMale = value;
OnPropertyChanged("IsMale");
OnPropertyChanged("IsFemale");
OnPropertyChanged("Description");
}
}
}
public bool IsFemale
{
get { return !isMale; }
set { IsMale = !value; }
}
public string Description
{
get
{
return isMale ? "Male" : "Female";
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
PropertyChanged(this, e);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
The main window xaml
<Grid>
<StackPanel DataContext="{Binding Current}">
<TextBlock Text="{Binding Name}"></TextBlock>
<RadioButton IsChecked="{Binding IsMale}">Male</RadioButton>
<RadioButton IsChecked="{Binding IsFemale}">Female</RadioButton>
<TextBlock Text="{Binding Description}"></TextBlock>
<Button Click="Button_Click" Height="32">Next >></Button>
<TextBlock>Note. Mary should be alway a female! But it changes when navigating by clicking the button above </TextBlock>
</StackPanel>
</Grid>
When you ask a question one StackOverflow, you really should provide all of the code required to reproduce your problem. The first reason that you should do this is so that people that are trying to help you don't have to waste time reproducing your code manually.
The second, more important reason is that when I had to reproduce your error with my own code (for the bits of code that you didn't show, eg. the
Person
class) then I have implemented the code properly, so your example code works just fine for me.Therefore, I can only assume that you have an error in your
Person
class, but as you didn't show that, I can't confirm it. My best guess is that you just didn't implement theINotifyPropertyChanged
correctly in thePerson
class, or maybe even your main class. When you do this, you should find that your code works just fine.