boaz23
boaz23

Reputation: 138

C# - Windows Forms User Control with Sub controls and data binding

I have created a rather simple user control with a few sub controls and components in it. I've added a single data binding between one of the components property to one of the controls property. So far so good, the problem arises when I add the user control to a form. The visual studio serializer adds that binding again in the form InitializeComponent method and therefore throwing an exception telling me that the property is already data bonded.

Another minor problem is that it also serializes the properties I've changed in the user control itself, even if I haven't changed them in the form. That problem might cause the problem above, I don't really know.

The user control code:

public partial class BrowseFolder : UserControl {
    private const string CATEGORY_CONTROLS = "Controls";

    public BrowseFolder() {
        InitializeComponent();
    }

    [Category(CATEGORY_CONTROLS)]
    [Description("The label that describes the folder's meaning in the context it's in.")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Label Label => this.Lbl;
    [Category(CATEGORY_CONTROLS)]
    [Description("The text box that displays or lets the user edit the full path of the folder.")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public TextBox TextBox_DirectoryFullPath => this.TxtBox_DirectoryFullPath;
    [Category(CATEGORY_CONTROLS)]
    [Description("The button that displays the folder browse dialog when clicked.")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Button Button_BrowseDirectory => this.Btn_BrowseDirectory;
    [Category(CATEGORY_CONTROLS)]
    [Description("The folder browse dialog.")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public NotifyPropertyChangedFolderBrowseDialog FolderBrowserDialog => this.Fbd;

    private void Btn_BrowseDirectory_Click(object sender, EventArgs e) =>
        this.FolderBrowserDialog.ShowDialog(this);

    private void InitializeComponent() {
        // initialize...

        // 
        // Btn_BrowseDirectory
        // 
        this.Btn_BrowseDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
        this.Btn_BrowseDirectory.Location = new System.Drawing.Point(365, 0);
        this.Btn_BrowseDirectory.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
        this.Btn_BrowseDirectory.Name = "Btn_BrowseDirectory";
        this.Btn_BrowseDirectory.Size = new System.Drawing.Size(75, 23);
        this.Btn_BrowseDirectory.TabIndex = 9;
        this.Btn_BrowseDirectory.Text = "Browse...";
        this.Btn_BrowseDirectory.UseVisualStyleBackColor = true;
        this.Btn_BrowseDirectory.Click += new System.EventHandler(this.Btn_BrowseDirectory_Click);
        // 
        // Lbl
        // 
        this.Lbl.AutoSize = true;
        this.Lbl.Location = new System.Drawing.Point(-3, 5);
        this.Lbl.Margin = new System.Windows.Forms.Padding(0);
        this.Lbl.Name = "Lbl";
        this.Lbl.Size = new System.Drawing.Size(31, 13);
        this.Lbl.TabIndex = 8;
        this.Lbl.Text = "Text:";
        // 
        // TxtBox_DirectoryFullPath
        // 
        this.TxtBox_DirectoryFullPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
        | System.Windows.Forms.AnchorStyles.Right)));
        this.TxtBox_DirectoryFullPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.Fbd, "SelectedPath", true));
        this.TxtBox_DirectoryFullPath.Location = new System.Drawing.Point(31, 2);
        this.TxtBox_DirectoryFullPath.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
        this.TxtBox_DirectoryFullPath.Name = "TxtBox_DirectoryFullPath";
        this.TxtBox_DirectoryFullPath.Size = new System.Drawing.Size(328, 20);
        this.TxtBox_DirectoryFullPath.TabIndex = 7;

        // initialize...
    }
    // controls fields declerations...
}

The form code:

class MyForm : Form {
    // other stuff...

    private void InitializeComponent() {
        // initialize...

        // browseFolder1
        // 
        // 
        // browseFolder1.Btn_BrowseDirectory
        // 
        this.browseFolder1.Button_BrowseDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
        this.browseFolder1.Button_BrowseDirectory.Location = new System.Drawing.Point(365, 0);
        this.browseFolder1.Button_BrowseDirectory.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
        this.browseFolder1.Button_BrowseDirectory.Name = "Btn_BrowseDirectory";
        this.browseFolder1.Button_BrowseDirectory.Size = new System.Drawing.Size(75, 23);
        this.browseFolder1.Button_BrowseDirectory.TabIndex = 9;
        this.browseFolder1.Button_BrowseDirectory.Text = "Browse...";
        this.browseFolder1.Button_BrowseDirectory.UseVisualStyleBackColor = true;
        // 
        // browseFolder1.Lbl
        // 
        this.browseFolder1.Label.AutoSize = true;
        this.browseFolder1.Label.Location = new System.Drawing.Point(-3, 5);
        this.browseFolder1.Label.Margin = new System.Windows.Forms.Padding(0);
        this.browseFolder1.Label.Name = "Lbl";
        this.browseFolder1.Label.Size = new System.Drawing.Size(31, 13);
        this.browseFolder1.Label.TabIndex = 8;
        this.browseFolder1.Label.Text = "Text:";
        this.browseFolder1.Location = new System.Drawing.Point(53, 86);
        this.browseFolder1.Margin = new System.Windows.Forms.Padding(3, 1, 3, 1);
        this.browseFolder1.Name = "browseFolder1";
        this.browseFolder1.Size = new System.Drawing.Size(440, 22);
        this.browseFolder1.TabIndex = 8;
        // 
        // browseFolder1.TxtBox_DirectoryFullPath
        // 
        this.browseFolder1.TextBox_DirectoryFullPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
        | System.Windows.Forms.AnchorStyles.Right)));
        this.browseFolder1.TextBox_DirectoryFullPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.browseFolder1.FolderBrowserDialog, "SelectedPath", true));
        this.browseFolder1.TextBox_DirectoryFullPath.Location = new System.Drawing.Point(31, 2);
        this.browseFolder1.TextBox_DirectoryFullPath.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
        this.browseFolder1.TextBox_DirectoryFullPath.Name = "TxtBox_DirectoryFullPath";
        this.browseFolder1.TextBox_DirectoryFullPath.Size = new System.Drawing.Size(328, 20);
        this.browseFolder1.TextBox_DirectoryFullPath.TabIndex = 7;

        // initialize...
    }
    // controls fields declerations...
} 

The exception being thrown: The exception being thrown

Upvotes: 2

Views: 1658

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125207

You have decorated your TextBox property with:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TextBox SomeTextBox { get { return someTextBox; } }

It means all properties of the SomeTextBox having a value different from the default value will be serialized.

To solve the problems about DataBinding, to prevent it from being serialized in form, in your user control add the data-binding if the control is not in design-mode:

if(LicenseManager.UsageMode != LicenseUsageMode.Designtime)
    someTextBox.DataBindings.Add("Text", SomeOtherControl, "SomeProperty", true);

Upvotes: 2

Related Questions