简体   繁体   English

更新ViewModel属性时如何避免递归?

[英]How can I avoid recursion when updating my ViewModel properties?

In my View I have a slider and a combobox . 在我的视图中,我有一个滑块和一个组合框

When I change the slider , I want the combobox to change. 当我更改滑块时 ,我希望组合框也要更改。

When I change the combobox , I want the slider to change. 更改组合框时 ,我希望滑块发生变化。

I can udpate one or the other, but if I try to update both I get a StackOverflow error since one property keeps updating the other in an infinite loop. 我可以叠加一个,但是如果我尝试同时更新两者,则会收到StackOverflow错误,因为一个属性会无限循环地更新另一个属性。

I've tried putting in a Recalculate() where the updating is done in one place, but still run into the recursion problem. 我尝试将Recalculate()放在一个地方进行更新的地方,但仍然遇到递归问题。

How can I have each control update the other without going into recursion? 如何让每个控件在不进行递归的情况下互相更新?

in View: 在视图中:

<ComboBox 
    ItemsSource="{Binding Customers}"
    ItemTemplate="{StaticResource CustomerComboBoxTemplate}"
    Margin="20"
    HorizontalAlignment="Left"
    SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"/>


<Slider Minimum="0" 
        Maximum="{Binding HighestCustomerIndex, Mode=TwoWay}" 
        Value="{Binding SelectedCustomerIndex, Mode=TwoWay}"/>

in ViewModel: 在ViewModel中:

#region ViewModelProperty: SelectedCustomer
private Customer _selectedCustomer;
public Customer SelectedCustomer
{
    get
    {
        return _selectedCustomer;
    }

    set
    {
        _selectedCustomer = value;
        OnPropertyChanged("SelectedCustomer");
        SelectedCustomerIndex = _customers.IndexOf(_selectedCustomer);
    }
}
#endregion

#region ViewModelProperty: SelectedCustomerIndex
private int _selectedCustomerIndex;
public int SelectedCustomerIndex
{
    get
    {
        return _selectedCustomerIndex;
    }

    set
    {
        _selectedCustomerIndex = value;
        OnPropertyChanged("SelectedCustomerIndex");
        SelectedCustomer = _customers[_selectedCustomerIndex];
    }
}
#endregion

try in the set functions something like: 尝试使用set函数,例如:

public int SelectedCustomerIndex
{
    get
    {
        return _selectedCustomerIndex;
    }

    set
    {
        if (value != _selectedCustomerIndex)
        {
         _selectedCustomerIndex = value;
         OnPropertyChanged("SelectedCustomerIndex");
         SelectedCustomer = _customers[_selectedCustomerIndex];
        }
    }
}

to fire the events only when there is an actual change in value. 仅在实际值发生变化时才触发事件。 This way, a second call to the set property with the same value does not cause another change event. 这样,第二次调用具有相同值的set属性不会导致另一个更改事件。

You have to do that for the other property as well of course. 当然,您也必须为其他属性执行此操作。

Both properties are called from each other, hence the recursion. 这两个属性是相互调用的,因此是递归的。 Not related to binding at all. 与绑定完全无关。 Proper way is to change each other and fire change notification for both properties when either property changes: 正确的方法是彼此更改并在两个属性中的任何一个发生更改时触发两个属性的更改通知:

    public Customer SelectedCustomer
    {
        get
        {
            return _selectedCustomerIndex;
        }

        set
        {
            _selectedCustomer = value;
            _selectedCustomerIndex = _customers.IndexOf(value);

            OnPropertyChanged("SelectedCustomer");
            OnPropertyChanged("SelectedCustomerIndex");
        }
    }

    public int SelectedCustomerIndex
    {
        get
        {
            return _selectedCustomerIndex;
        }

        set
        {
            _selectedCustomerIndex = value;
            _selectedCustomer = _customers[_selectedCustomerIndex];

            OnPropertyChanged("SelectedCustomer");
            OnPropertyChanged("SelectedCustomerIndex");
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我怎样才能避免递归? - How can I avoid the recursion? 如何在viewmodel中检测模型中属性的更改? - How can I dectect changes in properties inside my model in viewmodel? 如何绑定到 ViewModel 的属性和 ViewModel 中集合项的属性? - How can I bind to properties of the ViewModel and properties of collection items in the ViewModel? 如何避免ViewModel中的命令混乱? - How can I avoid command clutter in the ViewModel? 更新视图模型时如何避免RPC_E_WRONG_THREAD? - How can I avoid RPC_E_WRONG_THREAD when updating my View Model? 使用 C#,当用作 static 资源时,如何访问 ViewModel 的属性和方法? - Using C#, how can I access the ViewModel's properties and methods when used as a static resource? 如何在我的ViewModel中侦听来自另一个ViewModel的更改? - How can I listen in my ViewModel to changes from another ViewModel? 当我通过视图模型更改 currentUser 时,如何更新我的 XAML? - How can I update my XAML when I change currentUser via viewmodel? 序列化对象时如何加密选定的属性? - How can I encrypt selected properties when serializing my objects? 在视图之间导航时,如何防止我的 ViewModel 被实例化两次? - How can I prevent my ViewModel from being instantiated twice when navigating between views?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM