2009-04-08 11 views
6

WinForms, .NetFramework 3,5DataBind WinForm kontrolować za właściwość visible

Czy są jakieś znane problemy podczas wiązania z danymi do widocznego własności kontrolki za?

Sterowanie zawsze jest niewidoczne, niezależnie od tego, jaka jest moja własność.

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

Próbowałem właściwości text kontrolki i inne właściwości i wydaje się działać poprawnie.

Próbuję ustawić widoczną właściwość panelu.

Korzystanie ze źródła BindingSource.

Thx z góry.

+0

jak ty wiążąca? z kontrolką bindingsource lub deklaratywnie? –

+0

@matt - bindingsource –

+0

Może to mieć coś wspólnego z tym: http://stackoverflow.com/a/2570153/2455604 – Marwie

Odpowiedz

3

Obejście: Ustaw właściwość Widoczny w zdarzeniu BindingComplete.

Miałem ten sam problem z ustawieniem widocznej właściwości etykiety - zawsze pozostaje fałszem, nawet jeśli ustawienie właściwości Włączone działa dobrze.

1

Co należy sprawdzić:

  • Bądź pewien, że instancja klasy, która ma właściwość IsRibbonCategory
  • Czy ustawić źródło danych własności źródła wiążącego się z instancją klasy
  • tryb aktualizacji źródła danych powinny być na „weryfikacji”
  • Upewnij się, że nie ręcznie ustawić właściwość visible na false w sprawie kontroli

Nadzieję, że pomaga. Czy możesz dodać więcej kodu?

+0

Sprawdziłem wszystkie te, ale nie ma kości. Jedno pytanie, czy próbowałeś powiązania danych z widoczną własnością i zadziałało? –

+0

Tak. VS 2008/WinForm. Jakie zdarzenie używasz do ustawienia źródła danych formantu bindingsource? –

+0

Konstruktor formularza. –

8

Odkryłem, że życie jest lepsze, jeśli założymy, że wiązanie się z właściwością Visible kontrolki jest zepsute, mimo że czasami działa. Zobacz http://support.microsoft.com/kb/327305, który mówi tyle samo (i chociaż artykuł KB dotyczy .NET 1.0 i 1.1, nadal wydaje się być problem w co najmniej 2.0).

Utworzono klasę narzędzi do tworzenia wiązań, które między innymi dały mi scentralizowane miejsce do dodawania obejść. Zamiast faktycznie tworząc wiążące Widoczne robi dwie rzeczy:

  1. To subskrybuje przypadku źródła danych za INotifyPropertyChanged.PropertyChanged i ustawia wartość Visible to właściwe, gdy zdarzenie jest wywoływane.
  2. Ustawia wartość początkową Visible zgodnie z bieżącą wartością źródła danych.

Wymagało to trochę kodu odbicia, ale nie było tak źle. Bardzo ważne jest, aby nie wiązać właściwości Visible do obejścia lub nie zadziała.

+6

+1, i najwyraźniej nadal jest to prawda dla .NET 4. –

0

Obejście polegałoby na użyciu komponentu do powiązania danych z właściwością visiblity formantu, zamiast bezpośredniego wiązania z właściwością widoczności formantu. Zobacz poniżej kodu:

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

}

Powiązane problemy