Frage

Gibt es eine Möglichkeit zu sagen, wie das Combobox_Selection -Changed -Ereignis in WPF aufgebracht wurde?

Das heißt, wurde das Ereignis als Ergebnis einer Benutzerinteraktion oder als Ergebnis einer Änderung der Eigenschaft, an die sie gebunden ist?

War es hilfreich?

Lösung

Bei der Combobox.SelectionChanged -Veranstaltung ist der Absender stets Der Combobox und es gibt nichts in SelectionChangeDeDargs, das Ihnen helfen wird.

Zwei Lösungen dafür sind mir ein. Sie können einen Konverter für die Bindung verwenden oder die Stapelverfolgung überprüfen, um festzustellen, ob System.windows.controls.Primitive.Selector.OnlEctatedItemsCollectionChanged (Objekt, NotifyCollectionChangedargs) im Stapel. Der Stack -Check ist extrem hässlich, eine schlechte Praxis und arbeitet in teilweisen Vertrauensumgebungen nicht. Also werde ich nur den anderen beschreiben.

Verwenden eines Konverters auf der Bindung, um Änderungsquellen zu erkennen

Diese Lösung ist relativ sauber, erfordert jedoch eine Änderung der Bindung. Es benachrichtigt Sie auch manchmal, wenn sich die Dinge nicht geändert haben.

Schritt 1: Erstellen Sie einen Konverter, der keine Konvertierung durchführt, aber ein "konvertiertes" Ereignis und ein "konvertiertes" Ereignis hat:

public EventingConverter : IValueConverter
{
  public event EventHandler Converted;
  public event EventHandler ConvertedBack;

  public object Convert(object value, ...)
  {
    if(Converted!=null) Converted(this, EventArgs.Empty);
    return value;
  }
  public object ConvertBack(object value, ...)
  {
    if(ConvertedBack!=null) ConvertedBack(this, EventArgs.Empty);
    return value;
  }
}

Schritt 2: Stellen Sie Ihre Bindung so ein, dass eine neue Instanz dieses Konverters verwendet wird (teilen Sie den Konverterinstanzen nicht mit einem Ressourcenwörterbuch oder einer statischen Eigenschaft, wie es normalerweise ist).

<ComboBox ...>
  <ComboBox.SelectedValue>
    <Binding Path="..." ...>
      <Binding.Converter>
        <local:EventingConverter
          Converted="ComboBoxSelectedValue_Converted"
          ConvertedBack="ComboBoxSelectedValue_ConvertedBack" />
      </Binding.Converter>
    </Binding>
  </ComboBox.SelectedValue>
</ComboBox>

Jetzt werden Ihre ComboboxSelectedValue_Converted- und ComboboxSelectedValue_Convertedback -Methoden innerhalb des Bindungsprozesses aufgerufen.

Warnung: Wenn Sie eine Ausnahme in diesen Ereignissen machen, werden Sie die Bindung brechen.

Wenn Sie die XAML, die die Bindung durchführt, nicht ändern können

Wenn Sie keine Kontrolle über das XAML haben, das die Bindung erstellt (beispielsweise verwenden Sie beigefügte Eigenschaften), können Sie immer noch hereinkommen und den Konverter nach der Tatsache hinzufügen. In diesem Fall muss Ihre Konverterklasse an den zuvor deklarierten Konverter anketten, Sie müssen die Bindung klonen und das neue installieren (sie sind unveränderlich, sobald sie verwendet wurden), und Sie müssen sich auch mit Multibindings befassen (Wenn Sie sie unterstützen möchten).

Endgültige Anmerkung

Die Notwendigkeit zu bestimmen, ob die Änderung vom Benutzer oder der Eigenschaft vorgenommen wurde, kann tatsächlich ein Symptom für schlechte UI -Design sein, was normalerweise von Benutzern entsteht, die ihre eigenen Anforderungen nicht wirklich verstehen.

Ich hatte mehrere Projekte, an denen ich gearbeitet habe, wo der Endbenutzer angegeben hat, dass ein solcher und solcher Fall "Wenn ich diesen Combobox ändere". In fast jedem Fall hat sich herausgestellt, dass sich die Anwendung in bestimmten Anwendungsfällen unerwartet verhalten hätte und wir einen besseren Weg gefunden haben, um das Ziel zu erreichen. In vielen Fällen wollte der Benutzer wirklich "wenn dieser Wert zum ersten Mal von der in der Datenbank unterscheidet" oder "wenn dieser Wert nicht mehr standardmäßig ist" oder "wenn dieser Wert 5 ist".

Andere Tipps

Kurze Antwort: Nein. Es sollte keinen Unterschied geben, in beiden Fällen hat sich die Auswahl geändert, das ist alles, was zählt. Um festzustellen, ob es sich um eine Benutzerinteraktion handelte, müssen Sie eine Kombination anderer Ereignisse wie Dropdownopopeped/Closed und Keydown/Up und die Stylus* überwachen.

Ich habe diese Art von Problem auch getroffen und sie mit einem Booleschen bInternalChange Variable.

Stellen Sie sich eine Schnittstelle vor, die ° C in ° F und zurück mit zwei Comboboxen umwandelt. Auswählen eines Wertes in der ersten Aktualisierung der Auswahl der zweiten Aktualisierung und Auswahl eines Wertes in der zweiten Aktualisierung der ersten Aktualisierung. Es erzeugt eine unendliche Schleife, wenn Sie die Benutzeroberfläche nicht von internen Änderungen unterscheiden.

bool bInternalChange = false;
private void ComboBoxF_SelectionChanged(...)
{
    if (!bInternalChange)
    {
        bInternalChange = true;
        ComboBoxC.SelectedValue = ConvertFtoC(...);
        bInternalChange = false;
    }
}
private void ComboBoxC_SelectionChanged(...)
{
    if (!bInternalChange)
    {
        bInternalChange = true;
        ComboBoxF.SelectedValue = ConvertCtoF(...);
        bInternalChange = false;
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top