Wie binden Sie in diesem Szenario in WPF an eine Objektmethode?
public class RootObject
{
public string Name { get; }
public ObservableCollection<ChildObject> GetChildren() {...}
}
public class ChildObject
{
public string Name { get; }
}
XAML:
<TreeView ItemsSource="some list of RootObjects">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type data:RootObject}"
ItemsSource="???">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type data:ChildObject}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Hier möchte ich an die GetChildren
Methode in jedem RootObject
Baum binden .
BEARBEITEN Die Bindung an eine ObjectDataProvider
scheint nicht zu funktionieren, da ich an eine Liste von Elementen binde und ObjectDataProvider
entweder eine statische Methode benötige oder eine eigene Instanz erstellt und diese verwendet.
Wenn ich zum Beispiel Matts Antwort verwende, bekomme ich:
System.Windows.Data-Fehler: 33: ObjectDataProvider kann kein Objekt erstellen. Type = 'RootObject'; Fehler = 'Falsche Parameter für Konstruktor.'
System.Windows.Data-Fehler: 34: ObjectDataProvider: Fehler beim Aufrufen der Methode für den Typ; Methode = 'GetChildren'; Type = 'RootObject'; Fehler = 'Das angegebene Mitglied kann nicht auf dem Ziel aufgerufen werden.' TargetException: 'System.Reflection.TargetException: Für eine nicht statische Methode ist ein Ziel erforderlich.
quelle
Antworten:
Ein anderer Ansatz, der für Sie möglicherweise funktioniert, besteht darin, eine benutzerdefinierte
IValueConverter
Methode zu erstellen , die einen Methodennamen als Parameter verwendet, damit dieser wie folgt verwendet wird:Dieser Konverter würde die Methode unter Verwendung von Reflexion finden und aufrufen. Dies erfordert, dass die Methode keine Argumente hat.
Hier ist ein Beispiel für die Quelle eines solchen Konverters:
Und ein entsprechender Unit Test:
Beachten Sie, dass dieser Konverter den
targetType
Parameter nicht erzwingt .quelle
Sie sind sich nicht sicher, wie gut es in Ihrem Szenario funktioniert, aber Sie können die
MethodName
Eigenschaft on verwendenObjectDataProvider
, um eine bestimmte Methode (mit bestimmten Parametern von Ihnen) aufzurufenMethodParameters
Eigenschaft) , um die Daten abzurufen.Hier ist ein Ausschnitt, der direkt von der MSDN-Seite stammt:
Das ist also
ObjectDataProvider
eineConvertTemp
Methode , die eine Methode für eine Instanz einerTemperatureScale
Klasse aufruft und zwei Parameter (0
undTempType.Celsius
) übergibt .quelle
Müssen Sie sich an die Methode binden?
Können Sie sich an eine Eigenschaft binden, deren Getter die Methode ist?
quelle
Sofern Sie keine Eigenschaft zum Aufrufen der Methode hinzufügen können (oder eine Wrapper-Klasse erstellen, die diese Eigenschaft hinzufügt), ist die einzige mir bekannte Möglichkeit die Verwendung eines ValueConverter.
quelle
ObjectDataProvider verfügt auch über eine ObjectInstance-Eigenschaft, die anstelle von ObjectType verwendet werden kann
quelle
Sie können verwenden
System.ComponentModel
Eigenschaften für einen Typ dynamisch definieren (sie sind nicht Teil der kompilierten Metadaten). Ich habe diesen Ansatz in WPF verwendet, um die Bindung an einen Typ zu aktivieren, der seine Werte in Feldern gespeichert hat, da eine Bindung an Felder nicht möglich ist.Mit den Typen
ICustomTypeDescriptor
undTypeDescriptionProvider
können Sie möglicherweise das erreichen, was Sie möchten. Nach diesem Artikel :Ich habe diesen Ansatz nicht selbst ausprobiert, aber ich hoffe, er ist in Ihrem Fall hilfreich.
quelle
Um an die Methode eines Objekts in Ihrem WPF-Szenario zu binden, können Sie an eine Eigenschaft binden, die einen Delegaten zurückgibt.
quelle