Winform DataBind控制可见属性

时间:2009-04-08 16:21:21

标签: winforms data-binding .net-3.5

WinForms,.NetFramework 3.5

数据绑定到控件的可见属性时是否存在任何已知问题?

无论我的财产是什么,控件始终不可见。

Public ReadOnly Property IsRibbonCategory() As Boolean
    Get
        Return True
    End Get
End Property

我尝试了控件的文本属性和其他属性,它们似乎正常工作。

我正在尝试设置Panel的可见属性。

使用BindingSource。

提前谢谢。

6 个答案:

答案 0 :(得分:8)

我发现如果你认为绑定到控件的Visible属性会被破坏,生命会更好,尽管它有时会起作用。请参阅http://support.microsoft.com/kb/327305,其中说明了这一点(虽然知识库文章适用于.NET 1.0和1.1,但它似乎仍然是至少2.0的问题。)

我创建了一个用于创建绑定的实用程序类,除其他外,它为我提供了一个集中的地方来添加解决方法。而不是在Visible上实际创建绑定,它做了两件事:

  1. 它订阅了数据源的INotifyPropertyChanged.PropertyChanged事件,并在引发事件时将Visible值设置为适当的。
  2. 根据当前数据源值设置Visible的初始值。
  3. 这需要一点反射代码,但也不算太糟糕。至关重要的是,您不要绑定Visible属性进行解决方法,否则它将无效。

答案 1 :(得分:3)

解决方法:在BindingComplete事件上设置Visible属性。

我在设置标签的Visible属性时遇到了同样的问题 - 即使设置Enabled属性工作正常,也始终保持为false。

答案 2 :(得分:1)

要检查的事项:

  • 确保您已实例化具有IsRibbonCategory属性的类
  • 您是否已将绑定源的属性数据源设置为类
  • 的实例
  • 数据源更新模式应为“on validation”
  • 确保未在控件
  • 上手动将visible属性设置为false

希望有所帮助。你能发布更多代码吗?

答案 3 :(得分:1)

我刚在.NET 4.7.1和Visual Studio 2017中遇到此问题。要解决此问题,我将控件上的Visible属性更改为最初设置为True像以前的False

答案 4 :(得分:0)

解决方法是使用Component来数据绑定到控件的visibility属性,而不是直接绑定到控件的visibility属性。 见下面的代码:

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

namespace WindowsFormsApplication2
{
  public class ControlVisibilityBinding : Component
  {
    private static readonly object EventControlChanged = new object();
    private static readonly object EventVisibleChanged = new object();

    private System.Windows.Forms.Control _control;
    private bool _visible = true;

    public event EventHandler VisibleChanged
    {
        add { Events.AddHandler(EventVisibleChanged, value); }
        remove { Events.RemoveHandler(EventVisibleChanged, value); }
    }

    public event EventHandler ControlChanged
    {
        add { Events.AddHandler(EventControlChanged, value); }
        remove { Events.RemoveHandler(EventControlChanged, value); }
    }

    public ControlVisibilityBinding()
    {
    }

    public ControlVisibilityBinding(IContainer container)
    {
        container.Add(this);
    }

    [DefaultValue(null)]
    public System.Windows.Forms.Control Control
    {
        get { return _control; }
        set
        {
            if(_control == value)
            {
                return;
            }
            WireControl(_control, false);
            _control = value;
            if(_control != null)
            {
                _control.Visible = _visible;
            }
            WireControl(_control, true);
            OnControlChanged(EventArgs.Empty);
            OnVisibleChanged(EventArgs.Empty);
        }
    }

    [DefaultValue(true)]
    public bool Visible
    {
        get { return _visible; }
        set
        {
            if(_visible != value)
            {
                _visible = value;
            }
            if(Control != null)
            {
                Control.Visible = _visible;
            }
            OnVisibleChanged(EventArgs.Empty);
        }
    }

    private void WireControl(Control control, bool subscribe)
    {
        if(control == null)
        {
            return;
        }
        if(subscribe)
        {
            control.VisibleChanged += Control_VisibleChanged;
        }
        else
        {
            control.VisibleChanged -= Control_VisibleChanged;
        }
    }

    private void Control_VisibleChanged(object sender, EventArgs e)
    {
        OnVisibleChanged(EventArgs.Empty);
    }

    protected virtual void OnVisibleChanged(EventArgs e)
    {
        EventHandler subscribers = (EventHandler)Events[EventVisibleChanged];
        if(subscribers != null)
        {
            subscribers(this, e);
        }
    }

    protected virtual void OnControlChanged(EventArgs e)
    {
        EventHandler subscribers = (EventHandler)Events[EventControlChanged];
        if(subscribers != null)
        {
            subscribers(this, e);
        }
    }
}

static class Program
{
    [STAThread]
    static void Main()
    {
        using(Form form = new Form())
        using(FlowLayoutPanel groupBoxLayoutPanel = new FlowLayoutPanel())
        using(RadioButton visibleButton = new RadioButton())
        using(RadioButton hiddenButton = new RadioButton())
        using(GroupBox groupBox = new GroupBox())
        using(Label text = new Label())
        using(ControlVisibilityBinding visibilityBinding = new ControlVisibilityBinding())
        using(TextBox inputTextBox = new TextBox())
        {
            groupBoxLayoutPanel.Dock = DockStyle.Fill;
            groupBoxLayoutPanel.FlowDirection = FlowDirection.LeftToRight;
            groupBoxLayoutPanel.AutoSize = true;
            groupBoxLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;

            visibleButton.Text = "Show Label";
            visibleButton.AutoSize = true;
            hiddenButton.Text = "Hide Label";
            hiddenButton.AutoSize = true;
            groupBoxLayoutPanel.Controls.Add(visibleButton);
            groupBoxLayoutPanel.Controls.Add(hiddenButton);

            inputTextBox.Text = "Enter Label Text Here";
            inputTextBox.Dock = DockStyle.Top;

            groupBox.AutoSize = true;
            groupBox.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            groupBox.Controls.Add(groupBoxLayoutPanel);
            groupBox.Dock = DockStyle.Fill;

            text.AutoSize = true;
            text.ForeColor = Color.Red;
            text.Dock = DockStyle.Bottom;
            text.BorderStyle = BorderStyle.FixedSingle;
            text.Font = new Font(text.Font.FontFamily, text.Font.Size * 1.25f, FontStyle.Bold | FontStyle.Italic);
            text.DataBindings.Add("Text", inputTextBox, "Text", true, DataSourceUpdateMode.Never);

            visibilityBinding.Control = text;
            visibleButton.DataBindings.Add("Checked", visibilityBinding, "Visible", true, DataSourceUpdateMode.OnPropertyChanged);
            Binding binding = hiddenButton.DataBindings.Add("Checked", visibilityBinding, "Visible", true, DataSourceUpdateMode.OnPropertyChanged);
            ConvertEventHandler invertConverter = (sender, e) => e.Value = !((bool)e.Value);
            binding.Format += invertConverter;
            binding.Parse += invertConverter;

            form.Controls.Add(inputTextBox);
            form.Controls.Add(text);
            form.Controls.Add(groupBox);
            Application.Run(form);
        }
    }
}

}

答案 5 :(得分:0)

这是我的转身,它可能很愚蠢,但是它运行了很多次。

我在表单中放置了一个 Panel 控件,将其填充为 Fill 表单,然后将所有内容都放入了该面板中。我绑定 Visible 属性的所有控件都会根据DataGridView中的对象看到其可见性更改。

Form structure