代码隐藏中的数据绑定到CLR属性

在代码隐藏中很容易绑定到依赖属性。 您只需创建一个新的System.Windows.Data.Binding对象,然后调用目标依赖项对象的SetBinding方法。

但是当我们绑定的属性是CLR属性而你不能为SetBinding提供DependencyProperty参数时, SetBinding怎么SetBinding

编辑:对象实现INotifyPropertyChanged ,如果相关的话。

绑定目标必须是依赖属性! 这是数据绑定工作的唯一要求!

在这里阅读更多:

为了实现这一点,该属性必须是您正在为其编写setter的属性(因此,不是在代码中定义的属性,您无法更改)。
然后解决方案是实施属性更改通知 。

以上链接的示例代码:

 using System.ComponentModel; namespace SDKSample { // This class implements INotifyPropertyChanged // to support one-way and two-way bindings // (such that the UI element updates when the source // has been changed dynamically) public class Person : INotifyPropertyChanged { private string name; // Declare the event public event PropertyChangedEventHandler PropertyChanged; public Person() { } public Person(string value) { this.name = value; } public string PersonName { get { return name; } set { name = value; // Call OnPropertyChanged whenever the property is updated OnPropertyChanged("PersonName"); } } // Create the OnPropertyChanged method to raise the event protected void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } } } } 

在该实现中,每个属性设置器必须调用

 OnPropertyChanged("YourPropertyName"); 

或者对于稍微不同的实现,避免必须重新输入属性名称作为字符串参数, 请参阅我的答案 。
在那里,我还提到Fody / PropertyChanged,TinyMvvm和MvvmCross作为可以帮助实现这种模式的库。
(我正在使用Xamarin Forms,但我认为这些也可以从WPF中使用;它们基于System.ComponentModel命名空间。)

如果我正确理解了您的问题,那么您有一个FrameworkElement ,它暴露了一个未备份为Dependency属性的普通旧普通属性。 但是,您希望将其设置为绑定的目标。

首先让TwoWay绑定工作是不可能的,在大多数情况下是不可能的。 但是,如果您只想要一种方式绑定,那么您可以创建一个附加属性作为实际属性的代理。

让我们想象一下,我有一个StatusDisplay框架元素,它有一个字符串Message属性,对于某些非常愚蠢的原因,它不支持Message作为依赖属性。

 public static StatusDisplaySurrogates { public static string GetMessage(StatusDisplay element) { if (element == null) { throw new ArgumentNullException("element"); } return element.GetValue(MessageProperty) as string; } public static void SetMessage(StatusDisplay element, string value) { if (element == null) { throw new ArgumentNullException("element"); } element.SetValue(MessageProperty, value); } public static readonly DependencyProperty MessageProperty = DependencyProperty.RegisterAttached( "Message", typeof(string), typeof(StatusDisplay), new PropertyMetadata(null, OnMessagePropertyChanged)); private static void OnMessagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { StatusDisplay source = d as StatusDisplay; source.Message = e.NewValue as String; } } 

当然,如果StatusDisplay控件因任何原因直接修改了其Message属性,则此代理的状态将不再匹配。 对你的目的而言,这可能无关紧要。

等待。 你想绑定2个CLR属性吗? 让我说这样的事情是不可能以正常方式实现的。 例如。 没有任何一种可以使整个应用程序不稳定的核心黑客攻击。 绑定的一面必须是DependencyProperty。 期。

例如,您可以将CLR属性绑定到控件上的DepenencyProperty。 在这个cae中,CLR属性是绑定的SOURCE,DependencyProperty是绑定的TARGET。 要使其工作,具有CLR属性的类必须实现INotifyPropertyChanged。

以下是您在后面的代码中执行此操作的方法:

 Binding canModifyBinding = new Binding(); canModifyBinding.Source = LastRecord; canModifyBinding.Path = new PropertyPath( "CanModify" ); BindingOperations.SetBinding( this, CanModifyProperty, canModifyBinding ); 

在这种情况下,Binding对象表示有关Source的信息:什么对象是源,该对象的哪个属性是您感兴趣的.BindingOperations.SetBinding是一个静态方法,它指定DependencyObject所依赖的DependencyProperty。绑定的目标(分别为参数2和1),以及用于获取源的绑定。

HTH

托尼