2009-06-18 2 views
1

In meiner Ansicht habe ich eine Schieber und eine Combobox.Wie kann ich Rekursionen vermeiden, wenn ich meine ViewModel-Eigenschaften aktualisiere?

Wenn ich den Schieberegler ändern, möchte ich die Combobox ändern.

Wenn ich die Combobox ändern, möchte ich den Schieberegler ändern.

Ich kann die eine oder andere, aber wenn ich versuche, beide zu aktualisieren, bekomme ich eine StackOverflow Fehler, da eine Eigenschaft aktualisiert die andere in einer Endlosschleife.

Ich habe versucht, in eine Recalculate() wo die Aktualisierung an einem Ort erfolgt, aber immer noch in das Rekursionsproblem laufen.

Wie kann ich jedes Steuerelement aktualisieren das andere ohne in Rekursion gehen?

in Aussicht:

<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 Ansichtsmodell:

#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 

Antwort

7

Versuch in dem Set-Funktionen so etwas wie:

public int SelectedCustomerIndex 
{ 
    get 
    { 
     return _selectedCustomerIndex; 
    } 

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

die Ereignisse feuern nur, wenn es gibt eine tatsächliche Wertveränderung. Auf diese Weise verursacht ein zweiter Aufruf der Eigenschaft set mit demselben Wert kein anderes Änderungsereignis.

Das müssen Sie natürlich auch für die andere Immobilie tun.

+0

ausgezeichnet, ja, gearbeitet, dank –

+0

Diese in der Regel empfohlen, wenn Sie die Eigenschaften haben, die eine Property Ereignis auslösen, wie Sie sollte das Ereignis nur auslösen, wenn sich die Eigenschaft tatsächlich ändert. –

+1

Dies ist sehr naive Ansatz für das Problem (im Allgemeinen). Man kann nicht davon ausgehen, dass es zwischen den Bedeutungen keine Umrechnung gibt, der Wert kann (insbesondere bei reellen Zahlen) ** immer ** anders sein als vorher. Obwohl, wenn es funktioniert, gut, es funktioniert :-) – greenoldman

0

Beide Eigenschaften werden voneinander aufgerufen, daher die Rekursion. Nicht im Zusammenhang mit der Bindung überhaupt. Die richtige Weg ist, sich gegenseitig und Feuer-Änderungsbenachrichtigung für beide Eigenschaften zu ändern, wenn entweder Eigenschaftsänderungen:

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"); 
     } 
    } 
Verwandte Themen