【问题标题】:Exchange UserControls on a Form with data-binding在具有数据绑定的表单上交换用户控件
【发布时间】:2015-10-06 16:22:33
【问题描述】:

是否可以在 WinForms 中通过数据绑定交换两个 UserControl?

我想根据当前选择的 ComboBox 项目来更改应用程序 UI。我已将我的ComboBox.SelectedValue 绑定到一个属性,现在想在该属性的设置器中交换 UserControls。

我尝试在表单中添加一个大小相同的面板,并尝试将面板 DataSource 设置为 BindingList<Control> 或类似的东西,不幸的是,面板似乎没有类似于 ComboBoxDataSource。 ..

如果你能给我一个关于如何将我的 UserControl 数据绑定到我的表单的小提示,我会很高兴的。提前致谢。

【问题讨论】:

  • 只需制作一些面板并将它们放入您的表单中,然后根据您的组合框的选定项使其中一个可见,并将其他设置为不可见。它不需要这种数据绑定的技巧。

标签: c# winforms data-binding


【解决方案1】:

有点难,但可行。 WF 数据绑定的主要问题是缺乏对绑定表达式的支持。但是,只要源属性提供更改通知,就可以通过使用Binding.Format 事件并借助如下方法来解决:

static void Bind(Control target, string targetProperty, object source, string sourceProperty, Func<object, object> expression)
{
    var binding = new Binding(targetProperty, source, sourceProperty, true, DataSourceUpdateMode.Never);
    binding.Format += (sender, e) => e.Value = expression(e.Value);
    target.DataBindings.Add(binding);
}

与您的案例类似的用法示例:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Tests
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form = new Form();
            var topPanel = new Panel { Dock = DockStyle.Top, Parent = form };
            var combo = new ComboBox { Left = 8, Top = 8, Parent = topPanel };
            topPanel.Height = combo.Height + 16;
            combo.Items.AddRange(new[] { "One", "Two" });
            combo.SelectedIndex = 0;
            var panel1 = new Panel { Dock = DockStyle.Fill, Parent = form, BackColor = Color.Red };
            var panel2 = new Panel { Dock = DockStyle.Fill, Parent = form, BackColor = Color.Green };
            Bind(panel1, "Visible", combo, "SelectedIndex", value => (int)value == 0);
            Bind(panel2, "Visible", combo, "SelectedIndex", value => (int)value == 1);
            Application.Run(form);
        }
        static void Bind(Control target, string targetProperty, object source, string sourceProperty, Func<object, object> expression)
        {
            var binding = new Binding(targetProperty, source, sourceProperty, true, DataSourceUpdateMode.Never);
            binding.Format += (sender, e) => e.Value = expression(e.Value);
            target.DataBindings.Add(binding);
        }
    }
}

【讨论】:

  • 嘿伊万,感谢您的帮助。这是一个很好的提示,我可以使用 Format 作为条件(类似于 WPF 中的转换器)。我明白那里发生了什么,但我想,我会坚持我的二传手,好吧,我会看到的。但这里有另一个问题:那么包装面板是否必要?我不能只绑定用户控件的可见属性吗? (好吧,如果他们有的话)
  • @Jannik:这只是一个例子。关键是使用control.DataBindingsBindingsource 不需要是另一个控件,可以是任何具有targetProperty 的对象,即如果你已经有一个属性,你可以绑定到它。是的,您可以绑定任何控件的 Visible、Enabled 等属性 - 如您所见,目标上方的 Bind 方法声明为 Control,而不是 Panel,因此 UserControl 可以不使用问题。
猜你喜欢
  • 2012-03-29
  • 1970-01-01
  • 2013-11-24
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
相关资源
最近更新 更多