【问题标题】:Winforms DataBind to Control's Visible PropertyWinforms DataBind 到控件的 Visible 属性
【发布时间】:2010-10-18 08:40:58
【问题描述】:

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

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

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

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

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

【问题讨论】:

标签: winforms data-binding .net-3.5 bindingsource


【解决方案1】:

这是我的转变,它可能很愚蠢,但它工作了很多次。

我在我的表单中放置了一个面板控件,我让它填写我的表单,然后我将所有内容都放在了那个面板中。我绑定 Visible 属性的所有控件都会根据我的 DataGridView 中的对象看到它们的可见性变化。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 哇这工作,非常感谢!我将来会在每个控件上尝试它:P
    【解决方案3】:

    一种解决方法是使用组件将数据绑定到控件的可见性属性,而不是直接绑定到控件的可见性属性。 见以下代码:

    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);
            }
        }
    }
    

    }

    【讨论】:

      【解决方案4】:

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

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

      1. 它订阅数据源的 INotifyPropertyChanged.PropertyChanged 事件,并在引发事件时根据需要设置 Visible 值。
      2. 根据当前数据源值设置Visible的初始值。

      这需要一些反射代码,但还不错。关键是不要绑定 Visible 属性执行解决方法,否则它将不起作用。

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          检查事项:

          • 确保您已实例化具有 IsRibbonCategory 属性的类
          • 你是否将绑定源属性的数据源设置为类的实例
          • 数据源更新模式应为“验证时”
          • 确保您没有在控件上手动将可见属性设置为 false

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

          【讨论】:

          • 我已经检查了所有这些,但没有骰子。一个问题,您是否尝试过对可见属性进行数据绑定并且有效?
          • 是的。 VS 2008/Winforms。使用什么事件来设置 bindingsource 控件的数据源?
          • 你试过在表单的加载事件中调用 bindingsource.CurrencyManager.Refresh 吗?
          • 不,那没用。我会尝试把一个小原型放在一起
          猜你喜欢
          • 1970-01-01
          • 2011-05-23
          • 1970-01-01
          • 2011-04-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-04
          • 2010-11-04
          相关资源
          最近更新 更多