RichardD RichardD - 28 days ago 4
C# Question

How to swap property values in ViewModel? Can't pass by ref

I'd like to compare and swap the values of two ViewModel public properties, ideally using a method like this:

void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
T temp;
if (lhs.CompareTo(rhs) > 0)
{
temp = lhs;
lhs = rhs;
rhs = temp;
}
}


But as you can't pass properties by ref, I can't do this in my ViewModel.

private Int32 max;
public Int32 Max
{
get { return max; }
set
{
SwapIfGreater<Int32>(ref Min, ref Max);
max = value;
OnPropertyChanged("Max");
}
}

private Int32 min;
public Int32 Min
{
get { return min; }
set
{
SwapIfGreater<Int32>(ref Min, ref Max);
min = value;
OnPropertyChanged("Min");
}
}


Failing that... if I just try to use the "if compare" logic directly within the Min getter or setter, when Min is changed to a value greater than Max, I just end up with Min equal to Max.

EDIT: Based upon the advice about backing properties I've amended the method to this:

void SwapIfGreater<T>(ref T lhs, ref T rhs, String otherPropertyName) where T : System.IComparable<T>
{
T temp;
if (lhs.CompareTo(rhs) > 0)
{
temp = lhs;
lhs = rhs;
rhs = temp;
OnPropertyChanged(otherPropertyName);
}
}


and the "Min" Property setter to this:

min = value;
SwapIfGreater<Int32>(ref min, ref max, "Max");
OnPropertyChanged("Min");


What am I missing? This is still just setting Max to Min when Min is greater than Max.

EDIT: Although I'm keen to learn what I'm doing wrong above, having tested the UI again which implements the swap behaviour I wanted to replicate, I've realised it's a nasty UX, as the user is force to then click both pickers again. I'm going to revert to my original implementation of resetting Max to "No Maximum" if the user selects a Min higher than Max and vice versa.

Answer

You can not pass properties by ref because properties are translated to getter and setter methods.

Use the backing fields of properties instead

SwapIfGreater<Int32>(ref min, ref max);