2009-04-08 5 views
6

WinForms, .NetFramework 3,5Winforms DataBind Видимого свойства элемента управления в

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

Контроль всегда НЕ отображается независимо от того, что у меня есть.

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

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

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

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

Thx заранее.

+0

как вы связывании? с контролем связывания или декларативно? –

+0

@matt - bindingsource –

+0

Это может иметь какое-то отношение к этому: http://stackoverflow.com/a/2570153/2455604 – Marwie

ответ

3

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

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

1

Вещи, чтобы проверить:

  • Убедитесь, что вы экземпляр класса, который имеет свойство IsRibbonCategory
  • Вы установили источник данных о свойстве источника привязки к экземпляру класса
  • Режим обновления источника данных должен быть включен «on validation».
  • Убедитесь, что вы не установили видимое свойство вручную на значение false на элементе управления

Надеюсь, что помогает. Можете ли вы разместить больше кода?

+0

Я проверил все эти, но не кубики. Один вопрос, вы пытались привязать данные к видимой собственности, и это сработало? –

+0

Да. VS 2008/Winforms. Какое событие вы используете для установки источника данных элемента управления bindingsource? –

+0

Конструктор формы. –

8

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

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

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

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

+6

+1, и, по-видимому, это все еще верно для .NET 4. –

0

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

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

}

Смежные вопросы