在代码隐藏中很容易绑定到依赖属性。您只需创建一个新的System.Windows.Data.Binding
对象,然后调用目标依赖项对象的SetBinding
方法。
但是当我们绑定的属性是CLR属性而你无法向DependencyProperty
提供SetBinding
参数时,你怎么做呢?
编辑:如果相关,该对象会实现INotifyPropertyChanged
。
答案 0 :(得分:4)
绑定目标必须是依赖属性!这是数据绑定工作的唯一要求!
在这里阅读更多内容:
答案 1 :(得分:1)
为了实现这一目标,该属性必须是您正在编写setter的属性(因此,不是代码中定义的属性,您无法更改)。
然后解决方案是Implement Property Change Notification。
以上链接的示例代码:
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");
或者对于稍微不同的实现,可以避免必须将属性名称重新输入为字符串参数see my answer here。
在那里,我还提到Fody / PropertyChanged,TinyMvvm和MvvmCross作为可以帮助实现这种模式的库。
(我在Xamarin Forms中工作,但我认为这些也可以从WPF中使用;它们基于System.ComponentModel命名空间。)
答案 2 :(得分:0)
如果我正确理解了您的问题,那么您有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
属性,则此代理的状态将不再匹配。对你的目的而言,这仍然无关紧要。
答案 3 :(得分:0)
等待。 你想绑定2个CLR属性吗?让我说这样的事情是不可能以正常方式实现的。例如。没有任何一种可以使整个应用程序不稳定的核心黑客攻击。 绑定的一面必须是DependencyProperty。周期。
答案 4 :(得分:0)
例如,您可以将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是一个静态方法,它指定哪个DependencyProperty DependencyObject是绑定的目标(分别为参数2和1),以及用于获取源的Binding。
HTH
贝