WPF-Bindungsverhalten ist anders, wenn die gebundene Eigenschaft als Schnittstelle vs. Klassentyp deklariert ist?

8

Dies begann mit einem seltsamen Verhalten, das meiner Meinung nach mit meiner Implementierung von ToString() verbunden war, und ich stellte diese Frage: Warum zeigen WPF-Databindings keinen Text, wenn ToString () ein kollaborierendes Objekt hat?

Es stellt sich heraus, dass es nichts mit Kollaborateuren zu tun hat und reproduzierbar ist.

Wenn ich Label.Content an eine Eigenschaft von DataContext anbinde, die als Schnittstellentyp deklariert ist, wird ToString() für das Laufzeitobjekt aufgerufen und die Beschriftung zeigt das Ergebnis an.

Wenn ich TextBlock.Text an dieselbe Eigenschaft anhefte, wird ToString() niemals aufgerufen und nichts wird angezeigt. Aber , wenn ich die deklarierte Eigenschaft in eine konkrete Implementierung der Schnittstelle ändere, funktioniert sie wie erwartet.

Stimmt das irgendwie? Wenn ja, warum?

Um zu reproduzieren:

  • Erstellen Sie eine neue WPF-Anwendung (.NET 3.5 SP1)
  • Fügen Sie die folgenden Klassen hinzu:
%Vor%
%Vor%
  • Setzen Sie den XAML von Window1 auf:

    %Vor%
  • in Window1.xaml.cs:

%Vor%

Wenn Sie diese Anwendung ausführen, sehen Sie den Text nur einmal (oben, in der Bezeichnung). Wenn Sie den Typ der Eigenschaft foo in Bar class in Foo (anstelle von IFoo ) ändern und die Anwendung erneut ausführen, wird der Text in beiden Steuerelementen angezeigt.

    
Jay 27.05.2010, 01:06
quelle

2 Antworten

8

Ich weiß, dass dieser Thread alt ist, aber ich habe einen Workaround für dieses Problem gefunden. Verwenden Sie die StringFormat-Eigenschaft für die Bindung:

%Vor%     
Henrik 21.12.2012 15:15
quelle
3

Ja, Sie haben Recht. Offensichtlich ist die Eigenschaft ContentControl.Content anders implementiert als die Eigenschaft TextBlock.Text . Ein offensichtlicher Unterschied ist natürlich, dass ContentControl tatsächlich eine TextBlock -Instanz für ein Inhaltsobjekt erzeugt, das kein Visual ist und kein DataTemplate hat. Das TextBlock nicht. Es wird den Text selbst darstellen. In beiden Fällen wird die Zeichenfolge durch

bestimmt
  1. die IValueConverter (falls in der Bindung vorhanden)
  2. die TypeConverter (falls angegeben)
  3. object.ToString()

Es scheint, dass dieser Algorithmus sich nur in Schritt 3 zwischen TextBlock und ContentControl unterscheidet, wie Sie gezeigt haben. Während das ContentControl das Objekt hinter der Schnittstelle tatsächlich auflöst, tut dies TextBlock nicht. Interessant.

Ich schätze, das ist etwas, mit dem du leben musst. Sie haben jetzt mehrere Möglichkeiten:

  • Zeigen Sie eine string -Eigenschaft auf Ihrer Schnittstelle an und binden Sie diese an
  • Setzen Sie das Datenobjekt als konkrete Klasse statt als Schnittstelle
  • ein
  • Verwenden Sie ContentControl anstelle von TextBlock
  • liefert IValueConverter und verwendet es in der Bindung
  • stellen Sie ein TypeConverter für Ihre Schnittstelle bereit
  • tu etwas anderes (es gibt wahrscheinlich mehr)
bitbonk 27.05.2010 06:13
quelle

Tags und Links