Ticket T874994
Visible to All Users

PocoViewModel OnXXXChanged not working

created 5 years ago

Dear Support Team,

I'm working with a PocoViewModel. There a property is defined using an own class. In the PocoViewModel a OnChanged Method is implemented to the own class property but the OnChanged Method is not called even when a bound Textbox in XAML updates correctly.

The class:

C#
public class SubClass:BindableBase { public virtual string Text { get { return GetValue<string>(); } set { SetValue(value); } } }

Snippet of the PocoViewModel:

C#
public virtual SubClass TheSubClass { get; set; } ... public void OnTheSubClassChanged() { InfoText += Environment.NewLine + "OnTheSubClassChanged method done"; }

You can find a demonstration project attached.
A workaround I found is to inscribe to the PropertyChanged Event of the subclass and place my code in the event handler:

C#
[POCOViewModel] public class MainViewModel { public virtual SubClass TheSubClass { get; set; } public virtual string InfoText { get; set; } private int ChangeCnt = 0; public void ChangeText() { ChangeCnt++; TheSubClass.Text = "Text changed by command, change No " + ChangeCnt.ToString(); InfoText += Environment.NewLine + "Command ChangeText done!"; } public void OnTheSubClassChanged() { InfoText += Environment.NewLine + "OnTheSubClassChanged called"; } private void SubClassContentChanged(object sender, EventArgs e) { if (sender == null) return; InfoText += Environment.NewLine + "SubClassContentChanged called"; } #region poco constructor protected MainViewModel() { TheSubClass = new SubClass(); TheSubClass.Text = "Start Text"; TheSubClass.PropertyChanged += SubClassContentChanged; } public static MainViewModel Create() { return ViewModelSource.Create(() => new MainViewModel()); } #endregion }

Why is the OnXXXChanged method not called even the class has BindableBase implemented?
Regards
Martin

Answers approved by DevExpress Support

created 5 years ago

Hello Martin,

This behavior is expected. Such methods are called when a property changes completely

C#
TheSubClass = new SubClass();

POCO view models do not consider nested properties of an object in this case. The use of the PropertyChanged event looks OK to accomplish your task.

Let me know if you have additional questions.

    Show previous comments (6)

      Hello Alexander,
      thanks for your explanations. I tried afterward to solve my root problem, a GridControl with bound ColumsSource to an ObservableCollection and a ColumnGeneratorTemplateSelector. But I failed again. The approach to notify the ColumnSource was:

      C#
      public void ColumnsContentChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Remove) { foreach(Column item in e.OldItems) { item.PropertyChanged -= ListContentChanged; } } else if(e.Action== NotifyCollectionChangedAction.Add) { foreach (Column item in e.NewItems) { item.PropertyChanged += ListContentChanged; } } } public void ColumnsContentChanged(object sender, PropertyChangedEventArgs e) { this.RaisePropertyChanged(x => x.Columns); }

      In the constructor of the ViewModel the ColumnsContentChanged Method is subscribed to the ContentChanged Event of the ObservableCollection<Columns>.

      When the content of a single column class is changed, the ColumnsContentChanged Handler is called but the GridColumns doesn't update on changes. I assume the problem lies somewhere here:
      this.RaisePropertyChanged(x => x.Columns);

      Any idea?
      Regards
      Martin

        Sorry, wrong version, please have a look at his code:

        C#
        public void ColumnsContentChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Remove) { foreach(Column item in e.OldItems) { item.PropertyChanged -= ColumnsContentChanged; } } else if(e.Action== NotifyCollectionChangedAction.Add) { foreach (Column item in e.NewItems) { item.PropertyChanged += ColumnsContentChanged; } } } public void ColumnsContentChanged(object sender, PropertyChangedEventArgs e) { this.RaisePropertyChanged(x => x.Columns); }

        Thank you
        Martin

        Andrey Marten (DevExpress Support) 5 years ago

          Hello,

          I've created a separate ticket on your behalf (T875912: GridColumn is not updated based on an underlying column descriptor from ColumnsSource). It has been placed in our processing queue and will be answered shortly.

          Thanks,
          Andrey

          Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

          Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.