【问题标题】:C# how to implement databinding without Control?C#如何在没有Control的情况下实现数据绑定?
【发布时间】:2010-01-04 20:55:54
【问题描述】:

当两个类都不是 Control 类型时,有没有一种简单的方法来实现数据绑定?

就我而言,我想将变量绑定到自定义 ToolStripButton 的属性。

为澄清而编辑:绑定到控件时,我可以使用控件的 DataBindings 集合。但是,我正在寻找一种绑定属性的方法,而不管源类型和目标类型如何。

编辑:使用 winforms

【问题讨论】:

  • ToolStripButton 隐含 WinForms。
  • @bytenik 暗示还不够好,请参阅已经有一个仅与 WPF 相关的答案。

标签: c# winforms data-binding


【解决方案1】:

您可能可以通过使用Truss 来做到这一点。

Truss 为任何实现 INotifyPropertyChanged 的​​类提供 WPF 样式的数据绑定。它在这方面为您提供了更多的灵活性,因为它不会将类限制为从特定的基类派生。

【讨论】:

  • 感谢您的链接。我实际上并没有使用 Truss,但它为我指明了正确的方向,我可以推出自己的非常紧凑的 DataBinding 类:)
  • 你能给我们看一些代码吗?我需要在两个不同的自定义类中绑定一个属性..
【解决方案2】:

我在 ToolStripButton 上使用 IBindableComponent 的这个实现,找到 hereBindableToolStripButton 允许您像普通的Control 一样使用数据绑定。

[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class BindableToolStripButton : ToolStripButton, IBindableComponent
{

    public BindableToolStripButton()
        : base() { }
    public BindableToolStripButton(String text)
        : base(text) { }
    public BindableToolStripButton(System.Drawing.Image image)
        : base(image) { }
    public BindableToolStripButton(String text, System.Drawing.Image image)
        : base(text, image) { }
    public BindableToolStripButton(String text, System.Drawing.Image image, EventHandler onClick)
        : base(text, image, onClick) { }
    public BindableToolStripButton(String text, System.Drawing.Image image, EventHandler onClick, String name)
        : base(text, image, onClick, name) { }



    #region IBindableComponent Members
    private BindingContext bindingContext;
    private ControlBindingsCollection dataBindings;

    [Browsable(false)]
    public BindingContext BindingContext
    {
        get
        {
            if (bindingContext == null)
            {
                bindingContext = new BindingContext();
            }
            return bindingContext;
        }
        set
        {
            bindingContext = value;
        }
    }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public ControlBindingsCollection DataBindings
    {
        get
        {
            if (dataBindings == null)
            {
                dataBindings = new ControlBindingsCollection(this);
            }
            return dataBindings;
        }
    }
    #endregion

}

假设您有一个实现INotifyPropertyChanged 的类MyClass,就像绑定到控件属性时一样使用它:

bindableToolStripButton1.DataBindings.Add("Enabled", myClass1, "MyBooleanProperty");

【讨论】:

    【解决方案3】:

    使用依赖属性(您的 ToolStripButton 中的属性应该是)并在其他类中为您的变量创建一个属性,并创建一个绑定并将其设置为您的 ToolstripButton 的属性。

    我想这是最简单的方法。

    编辑:这仅适用于 WPF...

    否则实现 INotifyPropertyChanged 并且当您的变量更改时,它应该在您的 ToolStripButton 中自动更改。

    【讨论】:

    • Hmmm INotifyPropertyChanged 似乎可以做到这一点,但这也意味着我必须自己处理这两者之间的同步,对吧? IE。在两个方向上处理 PropertyChanged 事件。如果是这样,我认为这不会真的像数据绑定......
    • 但是,嘿...感谢您将我指向此界面。对于另一项任务来说非常好:)太好了。
    【解决方案4】:

    对于类似控件绑定到对象属性的行为,对于任何类型,您都可以实现相同的接口。

    基于这个想法,您可以继承 ToolStripButton(或希望的类型以具有绑定)并为其实现 IBindableComponent。这适用于所有类型的源和目标类型,只要它们不是sealed。例如,您的工具条按钮:

    public class BindableToolStripButton : ToolStripButton,  IBindableComponent {
        //...
    

    这将导致 BindableToolStripButton 拥有自己的 .DataBindings 属性,而基础 ToolStripButton 类没有这样的属性。

    您需要使用此处从 Microsoft 看到的示例来填写实现细节,这些示例针对 ISiteIBindableComponentIComponent 和任何继承的接口。

    然后您可以将Binding instances 添加到任何 BindableToolStripButton 实例。

    (注意:我只有片段,所以我将发布我的第一个社区 wiki 帖子 - 我们会看看结果如何......)

    【讨论】:

    • 谢谢,您的评论很有帮助。然而,我决定不使用这种技术,因为在我的例子中,有很多不同的类必须实现这些接口。所以我基于反射和 INotifyPropertyChanged(比 IBindableComponent 更容易实现)推出了自己的。
    【解决方案5】:

    我通过反射编写了一些基本的数据绑定内容。它适用于任何对象,不需要实现一些特殊的东西(没有 INotifyPropertyChanged,它只是工作)它是我的编辑器的一部分 http://github.com/filipkunc/opengl-editor-cocoa 查看 HotChocolate/Bindings(例如重新实现 Cocoa KVC、KVO 到 .NET ) 文件夹。您可以在 HotChocolateTest 项目中看到它的实际效果。

    【讨论】:

    • 谢谢,这看起来也很棒。不幸的是,当我完成自己的简单反射解决方案时,我才看到您的帖子。但是如果我需要其他功能,我一定会检查一下,谢谢!
    【解决方案6】:

    还有另一种快速简单的解决方案,即在表单中创建属性并绑定它们:

    public MyForm : Form
    {
        ...
    
        public bool CanDelete
        { 
            get { return deleteToolStripButton.Enabled; }
            set { deleteToolStripButton.Enabled = value; }
        }
    
        public MyForm()
        {
            ...
            this.DataBindings.Add("CanDelete", this.MyModel, "DeleteAllowed",
                                  false, DataSourceUpdateMode.Never);
            ...
        }
    }
    

    假设 MyModel 包含通知其更改的 DeleteAllowed 属性。

    【讨论】:

      猜你喜欢
      • 2013-09-18
      • 2021-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      相关资源
      最近更新 更多