Comment éviter la récursivité lors de la mise à jour de mes propriétés ViewModel?

StackOverflow https://stackoverflow.com/questions/1012812

  •  06-07-2019
  •  | 
  •  

Question

Dans ma vue, j'ai un curseur et une liste déroulante .

Lorsque je modifie le curseur , je souhaite que la liste déroulante soit modifiée.

Lorsque je changez la liste déroulante , je souhaite que le curseur change.

Je peux modifier l'un ou l'autre, mais si j'essaie de mettre à jour les deux, un erreur StackOverflow est mis à jour, une propriété continuant de mettre à jour l'autre dans une boucle infinie.

J'ai essayé de mettre en place Recalculate () , où la mise à jour est effectuée à un endroit, mais j'ai néanmoins rencontré le problème de la récursivité.

Comment puis-je demander à chaque contrôle de mettre à jour l'autre sans entrer en récursivité?

dans la vue:

<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}"/>

dans 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
Était-ce utile?

La solution

essayez dans les fonctions définies quelque chose comme:

public int SelectedCustomerIndex
{
    get
    {
        return _selectedCustomerIndex;
    }

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

pour déclencher les événements uniquement lorsqu'il y a un changement de valeur réel. De cette façon, un deuxième appel à la propriété set avec la même valeur ne provoque pas un autre événement de changement.

Vous devez bien sûr faire de même pour l'autre propriété.

Autres conseils

Les deux propriétés sont appelées l'une par l'autre, d'où la récursivité. Pas lié à la liaison du tout. Le moyen approprié est de se changer et d'activer la notification de modification pour les deux propriétés lorsque l'une de ces propriétés change:

    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");
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top