2009-04-08 6 views
6

WinForms Control, .NetFramework 3.5Winforms visible à la propriété DataBind

Y a-t-il des problèmes connus lors de databinding propriété visible d'un contrôle?

Le contrôle est toujours invisible quelle que soit ma propriété. J'ai essayé la propriété de texte du contrôle et d'autres propriétés et ils semblent fonctionner correctement. J'essaie de définir la propriété visible d'un Panel.

Utilisation d'une source de liaison.

Thx à l'avance.

+0

comment êtes-vous obligatoire? avec un contrôle bindingsource ou déclarative? –

+0

@matt - bindingsource –

+0

Cela a peut-être quelque chose à voir avec ceci: http://stackoverflow.com/a/2570153/2455604 – Marwie

Répondre

3

Solution de contournement: Définissez la propriété Visible sur l'événement BindingComplete.

J'ai eu le même problème en définissant la propriété Visible d'un label - reste toujours false, même si la définition de la propriété Enabled fonctionne correctement.

1

choses à vérifier:

  • Assurez-vous que vous avez instancié la classe qui a la propriété IsRibbonCategory
  • Avez-vous mis la source de données de la propriété de la source de liaison à l'instance de la classe
  • le mode de mise à jour devrait être source de données sur « la validation »
  • Assurez-vous de ne pas définir la propriété visible manuellement false sur le contrôle

Espérons que cela aide. Pouvez-vous poster plus de code?

+0

J'ai vérifié tout cela, mais pas de dés. Une question, avez-vous essayé la liaison de données à la propriété visible et cela a fonctionné? –

+0

Oui. VS 2008/Winforms. Quel événement utilisez-vous pour définir la source de données du contrôle bindingsource? –

+0

Le constructeur du formulaire. –

8

J'ai constaté que la vie est meilleure si vous supposez que la liaison à la propriété Visible d'un contrôle est rompue, malgré le fait que cela fonctionne parfois. Voir http://support.microsoft.com/kb/327305, qui en dit autant (et bien que l'article de la KB s'applique à .NET 1.0 et 1.1, il semble toujours être un problème dans au moins 2.0).

J'ai créé une classe utilitaire pour créer des liaisons qui, entre autres choses, m'a donné un endroit centralisé pour ajouter une solution de rechange. Au lieu de créer une réalité visible sur la liaison il fait deux choses:

  1. Il souscrit à l'événement INotifyPropertyChanged.PropertyChanged de la source de données et définit la valeur Visible selon le cas lorsque l'événement est soulevée.
  2. Il définit la valeur initiale de Visible en fonction de la valeur de la source de données actuelle.

Ceci nécessitait un peu de code de réflexion, mais n'était pas trop mauvais. Il est essentiel de ne pas lier la propriété visible et pour contourner le problème ou cela ne fonctionnera pas.

+6

+1, et apparemment c'est toujours vrai pour .NET 4. –

0

Une solution de contournement consiste à utiliser un composant pour la connexion de données à la propriété de visibilité d'un contrôle au lieu de se lier directement à la propriété de visibilité du contrôle. Voir ci-dessous le code:

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

}

Questions connexes