Winforms DataBind к видимому свойству элемента управления - PullRequest
6 голосов
/ 08 апреля 2009

WinForms, .NetFramework 3.5

Есть ли какие-либо известные проблемы при привязке данных к видимому свойству элемента управления?

Элемент управления всегда НЕ виден независимо от того, что является моей собственностью.

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

Я пробовал свойство text элемента управления и другие свойства, и они, похоже, работают правильно.

Я пытаюсь установить видимое свойство Panel.

Использование BindingSource.

Спасибо заранее.

Ответы [ 6 ]

8 голосов
/ 07 мая 2010

Я обнаружил, что жизнь лучше, если вы предполагаете, что привязка к свойству Visible элемента управления нарушена, несмотря на то, что иногда он работает. См. http://support.microsoft.com/kb/327305,, в котором говорится об этом (и хотя статья базы знаний относится к .NET 1.0 и 1.1, она все еще кажется проблемой по крайней мере в 2.0).

Я создал служебный класс для создания привязок, который, помимо прочего, дал мне централизованное место для добавления обходного пути. Вместо создания привязки в Visible он делает две вещи:

  1. Он подписывается на событие источника данных INotifyPropertyChanged.PropertyChanged и устанавливает значение Visible соответствующим образом при возникновении события.
  2. Устанавливает начальное значение Visible в соответствии с текущим значением источника данных.

Это потребовало небольшого кода отражения, но не так уж и плохо. Крайне важно, чтобы вы не связывали свойство Visible , а обходили его, иначе оно не будет работать.

3 голосов
/ 30 июля 2009

Обходной путь: установите свойство Visible для события BindingComplete.

У меня была такая же проблема при установке свойства Visible метки - всегда остается ложным, даже если настройка свойства Enabled работает нормально.

1 голос
/ 08 января 2019

Я только что столкнулся с этой проблемой в .NET 4.7.1 и Visual Studio 2017. Чтобы исправить это, я изменил свойство Visible в своем элементе управления, чтобы оно изначально было установлено на True, так как оно было False. ранее.

1 голос
/ 09 апреля 2009

Вещи для проверки:

  • Убедитесь, что вы создали экземпляр класса, обладающего свойством IsRibbonCategory
  • Вы установили источник данных свойства источника привязки для экземпляра класса
  • Режим обновления источника данных должен быть включен "при проверке"
  • Убедитесь, что вы не установили свойство visible вручную на false в элементе управления

Надеюсь, это поможет. Можете ли вы опубликовать больше кода?

0 голосов
/ 16 июня 2019

Вот мой оборот, это может быть глупо, но это работало много раз.

Я помещаю один Панель в мою форму, я делаю его Заполнить мою форму и помещаю все в эту Панель. Все элементы управления, с которыми я связываю свойство Visible , видят их изменения видимости в соответствии с объектами в моем DataGridView.

Form structure

0 голосов
/ 01 июня 2011

Обходной путь может заключаться в использовании компонента для привязки данных к свойству видимости элемента управления вместо прямой привязки к свойству видимости элемента управления. Смотрите ниже код:

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

}

...