2016-10-17 4 views
1

Я создал довольно простой пользовательский элемент управления с несколькими дополнительными элементами управления и компонентами. Я добавил единственную привязку данных между одним из свойств компонентов к одному из свойств элемента управления. Пока все хорошо, проблема возникает, когда я добавляю пользовательский элемент управления в форму. Серийный анализатор визуальной студии добавляет, что привязка снова в форме InitializeComponent и поэтому бросает исключение, сообщая мне, что свойство уже связано с данными.C# - Пользовательский элемент управления Windows Form с элементами управления Sub и привязкой данных

Еще одна небольшая проблема заключается в том, что она также сериализует свойства, которые я изменил в самом пользовательском элементе управления, даже если я не изменил их в форме. Эта проблема может вызвать проблему выше, я действительно не знаю.

Контрольный код пользователя:

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) полезным. –