2016-10-17 2846 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)有用。 –