C# 数据绑定到代码隐藏中的目标CLR属性

C# 数据绑定到代码隐藏中的目标CLR属性,c#,wpf,silverlight,data-binding,code-behind,C#,Wpf,Silverlight,Data Binding,Code Behind,在代码隐藏中,绑定到依赖项属性很容易。您只需创建一个新的System.Windows.Data.Binding对象,然后调用目标依赖项对象的SetBinding方法 但是,当我们绑定的属性是CLR属性,并且不能为SetBinding提供dependencProperty参数时,如何做到这一点?有没有办法将CLR属性用作绑定目标 编辑:对象实现了INotifyPropertyChanged,如果相关的话。绑定目标必须是依赖属性!这是数据绑定工作的唯一要求 请在此处阅读更多信息: 如果我正确理

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

但是,当我们绑定的属性是CLR属性,并且不能为
SetBinding
提供
dependencProperty
参数时,如何做到这一点?有没有办法将CLR属性用作绑定目标


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

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

请在此处阅读更多信息:


如果我正确理解了您的问题,您有一个
FrameworkElement
,它公开了一个普通的旧属性,而该属性没有作为依赖项属性进行备份。但是,您希望将其设置为绑定的目标

首先,将双向绑定到工作中是不可能的,而且在大多数情况下是不可能的。但是,如果只需要单向绑定,则可以创建附加属性作为实际属性的代理

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
framework元素,它有一个string
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属性绑定到控件上的DependencyProperty。在此cae中,CLR属性是绑定的源,DependencyProperty是绑定的目标。要使其工作,具有CLR属性的类必须实现INotifyPropertyChanged

下面是如何在代码隐藏中执行此操作:

Binding canModifyBinding = new Binding();
canModifyBinding.Source = LastRecord;
canModifyBinding.Path = new PropertyPath( "CanModify" );
BindingOperations.SetBinding( this, CanModifyProperty, canModifyBinding );
在本例中,绑定对象表示有关源的信息:源是什么对象,您感兴趣的是该对象的哪个属性。BindingOperations.SetBinding是一个静态方法,它指定哪个DependencyProperty,哪个DependencyObject是绑定的目标(分别为参数2和1),以及用于获取源的绑定


Tony

要实现这一点,属性必须是您正在为其编写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表单,但我认为这些表单也可以从WPF中使用;它们基于System.ComponentModel命名空间。)

我认为问题是关于绑定目标是CLR属性的问题;这就是你在这里的想法吗?(问题自您回答后已被编辑)