Bug Report T906028
Visible to All Users

Make the BindableBase.SetProperty method virtual

created 5 years ago

We have implemented a Undo/Redo-Manager based on your BindableBase class and your PropertyManager.
We used this to detect changes in the ViewModel and record them for Undo/Redo purposes.

Our BindableBase derived base class for all ViewModels looked like this:

C#
public class ChangeTrackingVm : BindableBase { private UndoPropertyManager _propertyManager; protected ChangeTrackingVm() { } protected UndoPropertyManager PropertyManager { get { return _propertyManager ?? (_propertyManager = new UndoPropertyManager(this)); } } protected override PropertyManager CreatePropertyManager() { return PropertyManager; } protected void InitProperty<T>(Expression<Func<T>> expression, T initValue) { SetPropertyCore(GetPropertyName(expression), initValue); } /// <summary> /// Sets property value without Undo-Tracking /// </summary> protected internal void SetPropertyCore<T>(string propertyName, T value) { PropertyManager.SetPropertyWithoutTracking(propertyName, value); } protected void AddPropertyAction<T>(string propertyName, T oldValue, T newValue) { if (UndoService.Service != null && GetType().GetProperty(propertyName)?.GetAttribute<NoUndoTrackingAttribute>() == null) { UndoService.Service?.AddPropertyAction(this, propertyName, oldValue, newValue); } } protected class UndoPropertyManager : PropertyManager { private readonly ChangeTrackingVm _viewModel; public UndoPropertyManager(ChangeTrackingVm viewModel) { _viewModel = viewModel; } protected override bool SetPropertyCore<T>(string propertyName, T value, out T oldValue) { bool result = base.SetPropertyCore(propertyName, value, out oldValue); _viewModel.AddPropertyAction(propertyName, oldValue, value); return result; } internal void SetPropertyWithoutTracking<T>(string propertyName, T value) { base.SetPropertyCore(propertyName, value, out _); } } }

Now you removed the PropertyManager and we are thinking about how to replace the lost functionality.
Your new BindableBase offers no virtual methods where we could dock our change detection logic.
Can you give us an idea how to solve this?

Ulrich

Answers approved by DevExpress Support

created 5 years ago

We have addressed the issue described in this ticket and will include a fix in our next maintenance update. To apply this solution before official release, request a hotfix by clicking the appropriate version link.

Note: Hotfixes may be unavailable for betas/updates set for release within a week.

    Comments (2)
    Dima (DevExpress Support) 5 years ago

      Just a quick follow-up. We marked methods with the following signatures virtual:

      C#
      SetProperty<T>(ref T storage, T value, string propertyName, Action changedCallback) SetPropertyCore<T>(string propertyName, T value, out T oldValue)
      UP UP
      Ulrich Proeller 5 years ago

        These are the ones, I need!

        created 5 years ago

        Hello Ulrich,

        Currently, BindableBase does not have a virtual method that you can override for the same purpose. It is necessary to declare a separate method in a BindableBase descendant and use it to set property values to cache them:

        C#
        public class ChangeTrackingVm : BindableBase { protected ChangeTrackingVm() { } protected void AddPropertyAction<T>(string propertyName, T oldValue, T newValue) { if (UndoService.Service != null && GetType().GetProperty(propertyName)?.GetAttribute<NoUndoTrackingAttribute>() == null) { UndoService.Service?.AddPropertyAction(this, propertyName, oldValue, newValue); } } protected void InitProperty<T>(Expression<Func<T>> expression, T initValue) { SetProperty(expression, initValue); } protected void SetPropertyWithTracking<T>(Expression<Func<T>> expression, T value) { AddPropertyAction(GetPropertyName(expression), GetProperty(expression), value); SetProperty(expression, value); } }

        Please try this approach and let me know if it is suitable.

          Show previous comments (1)
          Dima (DevExpress Support) 5 years ago

            You are right, Ulrich, this approach is not very convenient. I additionally discussed this scenario with our developers and we decided to make the required methods of the BindableBase class virtual. We will update this ticket once we have any news.

            UP UP
            Ulrich Proeller 5 years ago

              Thanks a lot, this is good news.

              Ulrich

              Dima (DevExpress Support) 5 years ago

                You're welcome!

                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.