2016-10-17 2824 views
1

我已经创建了一个相当简单的用户控件,其中包含一些子控件和组件。我在其中一个组件属性之间添加了单个数据绑定,并将其添加到其中一个控件属性中。到目前为止这么好,当我将用户控件添加到表单时出现问题。 Visual Studio序列化程序以InitializeComponent方法再次添加该绑定,因此抛出一个异常,告诉我该属性已经是数据绑定的。C# - 带子控件和数据绑定的Windows窗体用户控件

另一个小问题是,它还会序列化我在用户控件本身中更改的属性,即使我没有在表单中更改它们。这个问题可能会导致上述问题,我不知道。

用户控件代码:

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... 
} 

形式代码:

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

+0

没有详细了解什么你的控制是关于如果你想改变绑定到另一个源,你可以调用Control.DataBindings.Clear();来移除所有的绑定,然后添加新的绑定源。 – Koryu

回答

1

你装饰了你的TextBox属性搭配:

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

这意味着SomeTextBox具有不同于默认值的值的所有属性都将被序列化。

为了解决上述问题有关DataBinding,以防止它正在连载中的形式,在用户控件添加数据绑定,如果控制不处于设计模式:

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

非常感谢,购买方式,我很好奇LicenseManager类是什么。 – boaz23

+0

不客气。我用它来检测控制是否处于设计模式。 'DesignMode'属性在你的控件的构造函数中不起作用,所以我使用['LicenseManager.UsageMode'](https://msdn.microsoft.com/en-us/library/system.componentmodel.licensemanager.usagemode.aspx)。你可能会发现[这篇文章](http://stackoverflow.com/questions/1166226/detecting-design-mode-from-a-controls-constructor)有用。 –