1

Currently I have three properties in class MyClassOne. The number of properties may increase in future. Whenever any of the property changes, I need to call a method called SavePropertyToFile() which is responsible to set the corresponding property (AnotherPropertyOne, AnotherPropertyTwo or AnotherPropertyThree) of another class.

My sample code (which is of course not working) is below:

Class MyClassOne
{
        public bool PropertyOne
        {
            get => _propertyOne;
            set
            {
                if (_propertyOne == value)
                    return;

                _propertyOne = value;
                SavePropertyToFile(value, MyAnotherClass.AnotherPropertyOne); //<------------------
                NotifyOfPropertyChange(() => _propertyOne);
            }
        }


        public bool PropertyTwo
        {
            get => _propertyTwo;
            set
            {
                if (_propertyTwo == value)
                    return;

                _propertyTwo = value;
                SavePropertyToFile(value, MyAnotherClass.AnotherPropertyTwo); //<------------------
                NotifyOfPropertyChange(() => _propertyTwo);
            }
        }
        
        public bool PropertyThree
        {
            get => _propertyThree;
            set
            {
                if (_propertyThree == value)
                    return;

                _propertyThree = value;
                SavePropertyToFile(value, MyAnotherClass.AnotherPropertyThree); //<------------------
                NotifyOfPropertyChange(() => _propertyThree);
            }
        }       

        SavePropertyToFile(bool value, TProperty myPropertyOfAnotherClass)
        {
            myPropertyOfAnotherClass = value;
            
            // Some more lines of Code
            
            RefreshProgram();
        }
}  

In the code above, I need to find a way so that I can parse the correct property of AnotherClass. I already had a look at this another SO question, but I am not able to apply any of the answer for my case.

How can I parse different properties to a method?

Update: As per the suggestions in the comments, I have tried to use "Nathan Baulch" answer's option-2 but then I getting warning/error wiggly line as shown in the screenshot below:

enter image description here

skm
  • 5,015
  • 8
  • 43
  • 104
  • 3
    " I can parse " in the link you provided they talk about *passing* which is very much different from parsing, which one is it? – Mong Zhu Feb 10 '23 at 13:07
  • 2
    How do you match up `PropertyThree` with `AnotherPropertyThree`? – gunr2171 Feb 10 '23 at 13:07
  • 3
    "but I am not able to apply any of the answer for my case" Please show your attempts. Option 2 in Nathan Baulch's answer there looks totally applicable. – Sweeper Feb 10 '23 at 13:08
  • 1
    I would just move the assignment to outside of the method. Other than that you can use `Action` or `Action` which will assign the value (UPD as mentioned previously - option 2 of the accepted answer linked in the OP). – Guru Stron Feb 10 '23 at 13:10
  • 1
    Why don't you register `AnotherClass` for the respective propertyChanges that `MyClassOne` notifies of ? – Fildor Feb 10 '23 at 13:16
  • 1
    @Sweeper: It's not working, I have updated the issue in my OP. – skm Feb 10 '23 at 13:21
  • 1
    You are doing it wrong. `Action SomeAction` is a delegate of the form `void SomeAction(bool arg)` , so you need to do `targetProperty(inputValue);` – Fildor Feb 10 '23 at 13:23
  • 1
    Or if you want that null-safe: `targetProperty?.Invoke(inputValue);` – Fildor Feb 10 '23 at 13:25
  • 1
    @Fildor: Worked like that! Thanks! – skm Feb 10 '23 at 13:31

1 Answers1

1

If the idea is to make several classes use the same property, my approach is to wrap the values in a class:

public class Changeable<T> : INotifyPropertyChanged
{
    private T currentValue;

    public Changeable(T initialValue) => currentValue = initialValue;

    public T Value
    {
        get => currentValue;
        set
        {
            if (!EqualityComparer<T>.Default.Equals(currentValue, value))
            {
                this.currentValue = value;
                Changed?.Invoke(this, value);
                OnPropertyChanged(nameof(Value));
            }
        }
    }

    public event EventHandler<T> Changed;
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

You can then just let both classes use the same actual object. This approach can also be used to cut down on boilerplate for wpf, instead of declaring getters and setters you can just write:

public Changeable<bool> MyProperty {get;} => new (false);

Just remember to update the binding: {Binding MyProperty.Value}

You can also write various extensions. For example if you want to update one property whenever some other property updates:

MyProperty.BindTo(MyIntProperty, intValue => intValue > 0);

So whenever MyIntProperty changes sign, the MyProperty would be updated and raise its changed event. I'm not going to include all the code behind this, since it is fairly large, but I hope you get the idea. This approach makes it possible to link various UI values in a convenient way, but it can also make the code more difficult to understand and debug, so some caution is advised.

JonasH
  • 28,608
  • 2
  • 10
  • 23