Nếu bạn tạo ràng buộc trong mã phía sau thì bạn có thể làm cho nó hoạt động. Ví dụ: mã đơn giản được tạo ràng buộc là:
Binding binding = new Binding("BindingPath");
binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(textBoxName, TextBox.TextProperty, binding);
Vì đường dẫn trong ràng buộc này ("BindingPath") chỉ là một chuỗi, chuỗi đó có thể đến từ bất kỳ đối tượng có sẵn nào.
Bạn sẽ cần phải móc vào việc tạo các mục dữ liệu của mình để đặt các ràng buộc này.
Một khả năng tiếp tục dựa trên ý kiến của bạn:
This blog post vạch ra một cách để tạo một lớp tùy chỉnh ràng buộc bởi kế thừa từ MarkupExtension. Bạn có thể sử dụng điều này làm điểm bắt đầu để đưa đề xuất của tôi vào đánh dấu xaml có thể tái sử dụng cho trường hợp ràng buộc đặc biệt của bạn.
More suy nghĩ:
Được rồi, đây là một vấn đề thú vị, vì vậy tôi đã quyết định dành một ít thời gian nhìn thấy nếu tôi có thể đưa ra một giải pháp làm việc. Tôi xin lỗi trước cho độ dài của các mẫu mã sau ...
Căn giải pháp của tôi trên bài đăng blog tôi liên kết với trên, chúng tôi tạo ra lớp này:
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;
}
Bạn có thể sử dụng đánh dấu mới này với theo xaml:
<TextBox Text="{local:IndirectBinder IndirectProperty=FieldValuePath}"/>
Trường hợp TextBox có thể là bất kỳ lớp nào thừa kế từ kiểm soát và Văn bản có thể là bất kỳ thuộc tính phụ thuộc nào.
Rõ ràng nếu bạn cần phơi bày bất kỳ tùy chọn dữ liệu nào khác (chẳng hạn như một hoặc hai cách liên kết) thì bạn sẽ cần phải thêm các thuộc tính khác vào lớp.
Trong khi đây là một giải pháp phức tạp, một lợi thế mà nó có hơn bằng cách sử dụng bộ chuyển đổi là ràng buộc cuối cùng được tạo là chống lại thuộc tính bên trong thực tế chứ không phải đối tượng. Điều này có nghĩa là nó phản ứng chính xác với các sự kiện PropertyChanged.
tốt, đây là một cách tiếp cận có thể hoạt động, nhưng tôi thực sự muốn có thể tạo Bindings trong XAML, bởi vì tôi đang lập kế hoạch viết có thuộc tính ràng buộc khác nhau tùy thuộc vào trạng thái của dữ liệu cơ bản. Nhưng có thể tôi thực sự có thể cố gắng viết tất cả logic này trong đoạn mã sau ... – arconaut
và bên cạnh đó, nó không chỉ là TextBlock mà tôi đang định chỉ định ràng buộc. Nó được coi là một trình soạn thảo/trình xem cho bất kỳ thuộc tính nào trên bất kỳ đối tượng nào. Tôi nghĩ rằng tôi nên thêm vào bài viết hàng đầu. – arconaut
cảm ơn câu trả lời và cảm ơn liên kết. Tôi sẽ thử điều này ra – arconaut