Usuário com melhor resposta
INotifyPropertyChanged não notificar o objeto pai dos elementos ?

Pergunta
-
Olá pessoal,
Estou com e seguinte problema:
- Criei uma classe chamada AllPersons que tem um objeto do tipo Person chamado Persona
- O objeto Person por sua vez possui duas propriedades Name e Addr que é um objeto do tipo Address
- O objeto Address tem apenas uma propriedade chamada Street.
Todas as classes tem implementada a interface INotifyPropertyChanged para quando qualquer uma das propriedades tiverem seus valores modificados o elemento WPF que estiver conectado a ela seja notificado também. Exemplo:
<StackPanel DataContext="{DynamicResource AllPersons}">
<Label Background="LightGray" Content="{Binding Path=Persona, UpdateSourceTrigger=PropertyChanged}" />
<Label Background="LightGray" Content="{Binding Path=Persona.Name, UpdateSourceTrigger=PropertyChanged}"/>
<Label Background="LightGray" Content="{Binding Path=Persona.Addr.Street, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
O PROBLEMA:
Caso eu altere os valores de qualquer elemento dentro do object Persona a propriedade que foi modificada é notificada normalmente, MAS O OBJETO PERSON NÃO RECEBE NOTIFICACÃO.
O objeto persona somente recebe uma notificacao de modificacao no momento em que ele é criado.
allPersons.Persona = new Person { Name = "Mike Rexeas", Addr = new Address { Street = "Street One,14" } };
Alguem pode me informar porque isto acontece e como solucionar este problema ?
Tem como notificar o "pai" sempre que uma propriedade dele for modificada ?
Na verdade este é um exemplo de classes que enviei apenas para ver se alguem consegue me ajudar.
O meu projeto verdadeiro é o seguinte eu tenho uma classe com todos os elementos relacionados as cores de uma fonte de tela onde posso manipula-las num editor, entao eu faço um binding de cada um destes objetos por exemplo (SettingsForLabel1) e quando o usuario modifica as propriedades deste objeto, exemplo SettingsForLabel1.Background o element que esta conectado a este binding deve ser atualizado. O que está acontecendo é que somente é atualizado um elemento cujo binding estiver relacionado a uma propriedades especifica do objeto SettingsForLabel1. Por exemplo se eu ligar SettingForLabel1.Background a Label1.Background o fundo de label1 é modificado normalmente.
public partial class Window1 : Window
{
AllPersons allPersons = new AllPersons();public Window1()
{
InitializeComponent();
this.Resources["AllPersons"] = allPersons;
}private void button1_Click(object sender, RoutedEventArgs e)
{
allPersons.Persona.Name = "Mickey Mouse " + DateTime.Now.ToLongTimeString(); ;
}private void button2_Click(object sender, RoutedEventArgs e)
{
allPersons.Persona.Addr.Street = "St.Mouris street " + DateTime.Now.ToLongTimeString(); ;
}private void button3_Click(object sender, RoutedEventArgs e)
{
allPersons.Persona = new Person { Name = "Mike Rexeas", Addr = new Address { Street = "Street One,14" } };
}
}public class AllPersons : INotifyPropertyChanged
{
private Person person;public Person Persona
{
get { return person; }
set
{
person = value;
this.OnPropertyChanged("Persona");
}
}public AllPersons()
{
Persona = new Person();
Persona.Name = "Peter Parker";
Persona.Addr = new Address { Street = "Elm street" };
}#region NotifyPropertyChanged
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}/// <summary>
/// Raises the <see cref="PropertyChanged"/> event.
/// </summary>
/// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eventHandlers = this.PropertyChanged;
if (null != eventHandlers)
eventHandlers(this, e);
}
#endregionpublic override string ToString()
{
return "AllPerson changed at " + DateTime.Now.ToLongTimeString();
}
}public class Person : INotifyPropertyChanged
{
private string name;
private Address addr;public Address Addr
{
get { return addr; }
set
{
addr = value;
this.OnPropertyChanged("Addr");
}
}public string Name
{
get { return name; }
set
{
name = value;
this.OnPropertyChanged("Name");
}
}public Person()
{
Name = "Tony Stark";
Addr = new Address();
Addr.Street = "Iron Street";
}
public override string ToString()
{
return DateTime.Now.ToLongTimeString() + ">>Person=" + this.Name + " Adr=" + this.Addr.Street;
}#region NotifyPropertyChanged
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}/// <summary>
/// Raises the <see cref="PropertyChanged"/> event.
/// </summary>
/// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eventHandlers = this.PropertyChanged;
if (null != eventHandlers)
eventHandlers(this, e);
}
#endregion
}public class Address : INotifyPropertyChanged
{
private string street;public string Street
{
get { return street; }
set
{
street = value;
this.OnPropertyChanged("Street");
}
}#region NotifyPropertyChanged
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}/// <summary>
/// Raises the <see cref="PropertyChanged"/> event.
/// </summary>
/// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eventHandlers = this.PropertyChanged;
if (null != eventHandlers)
eventHandlers(this, e);
}
#endregion
}Obrigado
Edson
Respostas
-
Sugiro que voce use para o seu caso a coleção observableCollection, pois ela consegui disparar as notificações.
- Sugerido como Resposta Thiago MDTech quinta-feira, 15 de abril de 2010 16:40
- Marcado como Resposta AndreAlvesLimaModerator sexta-feira, 7 de maio de 2010 23:02