none
INotifyPropertyChanged não notificar o objeto pai dos elementos ? RRS feed

  • 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);
            }
            #endregion

            public 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

     

    quinta-feira, 15 de abril de 2010 13:42

Respostas