如何在ViewModel交换属性值?不能通过裁判

本文关键字:不能 ViewModel 交换 属性 | 更新日期: 2023-09-27 18:17:41

我想比较和交换两个ViewModel公共属性的值,理想情况下使用这样的方法:

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;
    }
}

但是你不能通过ref传递属性,我不能在我的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");
    }
}

失败……如果我只是尝试在Min getter或setter中直接使用"if比较"逻辑,当Min更改为大于Max的值时,我只是以Min等于Max结束。

EDIT:根据关于支持属性的建议,我已将方法修改为:

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);
    }            
}

和"Min"属性设置为:

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

我错过了什么?当最小值大于最大值时,这仍然只是将最大值设置为最小值。

EDIT:虽然我很想知道我上面做错了什么,但在再次测试了实现我想要复制的交换行为的UI后,我意识到这是一个讨厌的UX,因为用户被迫再次点击两个选择器。如果用户选择的最小值高于最大值,我将恢复到将Max重置为"No Maximum"的原始实现,反之亦然。

如何在ViewModel交换属性值?不能通过裁判

不能通过ref传递属性,因为属性会被转换为getter和setter方法。

使用属性的后备字段而不是

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

当你传递一个参数为ref时,它的地址被传递。属性看起来像一个值,但它实际上是一对函数,每个函数都有不同的签名。因此,要传递属性,实际上需要传递两个函数指针,一个用于get,一个用于set。

传递给函数和传递给变量

的地址是完全不同的

。一个变量指向v的两个函数指针。

因此,尽量避免将属性作为Ref或Out传递。

医生已经给你提供了正确的解决方案。

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