Wenn Sie die Bindung in den Code hinter erstellen, dann könnten Sie es zum Laufen bringen. Zum Beispiel ist ein einfacher Code erzeugte Bindung:
Binding binding = new Binding("BindingPath");
binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(textBoxName, TextBox.TextProperty, binding);
Da der Weg in dieser Bindung („BindingPath“) ist nur eine Zeichenfolge, könnte diese Zeichenfolge kommt aus jedem beliebigen Objekt.
Sie müssen jedoch in die Erstellung Ihrer Datenelemente eingreifen, um diese Bindung festzulegen.
Eine weitere Möglichkeit, basierend auf Ihre Kommentare:
This blog post beschreibt eine Möglichkeit, eine benutzerdefinierte Bindung Klasse durch Erben von Markupextension zu erstellen. Sie können dies möglicherweise als Ausgangspunkt verwenden, um meinen Vorschlag in ein wiederverwendbares Xaml-Markup für Ihren speziellen Bindungsfall einzubetten.
Weitere Gedanken:
Okay, das war ein interessantes Problem, so habe ich beschlossen, zu sehen, eine wenig Zeit zu verbringen, wenn ich mit einer Arbeitslösung kommen könnte. Ich entschuldige mich für die Länge der folgenden Codebeispiele im Voraus ...
Gründend meine Lösung auf der Blog-Post ich oben I verknüpfen diese Klasse erstellt:
public class IndirectBinder : MarkupExtension
{
public string IndirectProperty { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
//try to get bound items for our custom work
DependencyObject targetObject;
DependencyProperty targetProperty;
bool status = TryGetTargetItems(serviceProvider, out targetObject, out targetProperty);
if (status)
{
Control targetControl = targetObject as Control;
if (targetControl == null) return null;
//Find the object to take the binding from
object dataContext = targetControl.DataContext;
if (dataContext == null) return null;
//Reflect out the indirect property and get the value
PropertyInfo pi = dataContext.GetType().GetProperty(IndirectProperty);
if (pi == null) return null;
string realProperty = pi.GetValue(dataContext, null) as string;
if (realProperty == null) return null;
//Create the binding against the inner property
Binding binding = new Binding(realProperty);
binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(targetObject, targetProperty, binding);
//Return the initial value of the binding
PropertyInfo realPi = dataContext.GetType().GetProperty(realProperty);
if (realPi == null) return null;
return realPi.GetValue(dataContext, null);
}
return null;
}
protected virtual bool TryGetTargetItems(IServiceProvider provider, out DependencyObject target, out DependencyProperty dp)
{
target = null;
dp = null;
if (provider == null) return false;
//create a binding and assign it to the target
IProvideValueTarget service = (IProvideValueTarget)provider.GetService(typeof(IProvideValueTarget));
if (service == null) return false;
//we need dependency objects/properties
target = service.TargetObject as DependencyObject;
dp = service.TargetProperty as DependencyProperty;
return target != null && dp != null;
}
Sie können diese neue Markup mit dem Einsatz folgende xAML:
<TextBox Text="{local:IndirectBinder IndirectProperty=FieldValuePath}"/>
Wo TextBox jede Klasse sein kann, die von der Kontrolle und Text erbt kann jede Abhängigkeitseigenschaft sein.
Offensichtlich müssen Sie der Klasse weitere Eigenschaften hinzufügen, wenn Sie andere Datenbindungsoptionen verfügbar machen müssen (z. B. ein- oder zweiseitige Bindung).
Während dies eine komplizierte Lösung ist, hat ein Vorteil gegenüber einem Konverter, dass die Bindung, die schließlich erstellt wird, gegen die tatsächliche innere Eigenschaft und nicht gegen das Objekt gerichtet ist. Dies bedeutet, dass es korrekt auf PropertyChanged-Ereignisse reagiert.
Nun, dies ist ein Ansatz, der funktionieren könnte, aber ich würde wirklich gerne Bindungen in XAML erstellen können, weil ich verschiedene Schreibeigenschaften schreiben möchte, abhängig vom Zustand der zugrunde liegenden Daten. Aber möglicherweise könnte ich tatsächlich versuchen, all diese Logik in den Code-hinter zu schreiben ... – arconaut
und außerdem, es ist nicht nur TextBlock, den ich für verbindlich festlegen möchte. Es sollte ein Editor/Viewer für jede Eigenschaft eines Objekts sein. Ich denke, ich sollte zum Top Post hinzufügen. – arconaut
danke für die antwort, und danke für den link. Ich werde das ausprobieren – arconaut