рдорд╛рдирдХ WinForms TabControl рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░

рдпрд╣ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╣реБрдЖ рдХрд┐ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЯреИрдмрдХрдВрдЯреНрд░реЛрд▓ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдорд╛рдирдХ рдШрдЯрдХ, рдХреБрдЫ рднреА рдЕрд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ, рдХрд╛рдлреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХред рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдпрд╣ рдереА рдХрд┐ рдЖрдкрдХреЛ рдПрдХ рдЕрддрд┐рднрд╛рд░рд┐рдд рдЯреИрдмрдкреЗрдЬ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрдкрдиреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреИрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдерд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕реНрд╡рдпрдВ рдЯреИрдм рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдЗрд╕реЗ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджреЗрдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
рдЫрд╡рд┐

рдореБрдЭреЗ рдЦреБрд╢реА рд╣реИ рдХрд┐ рдорд╛рдирдХ рдШрдЯрдХ рдЖрдкрдХреЛ рдЙрдирдХреЗ рд╕рд╛рде рдмрд╣реБрдд рд╕рд╛рд░реА рд╡рд┐рдХреГрддрд┐рдпрд╛рдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред


рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВ ред 2011 рдХреЗ 2010 рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреЗ рддрд╣рддред

рдЪрд▓реЛ рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреИрдм рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ ред
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, DataGridViewColumn рдХреЗ рд╡рд┐рдкрд░реАрдд, TabControl рдПрдХ рдЖрдВрддрд░рд┐рдХ рдЪрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдиреЗрд╕реНрдЯреЗрдб рддрддреНрд╡ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рддреЛ рдпрд╣ DataGridViewColumn рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
public class CustomDataGridViewColumn : DataGridViewTextBoxColumn { public CustomDataGridViewColumn() { this->CellTemplate = CustomDataGridViewCell; } } 


рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдиреЗрдЯ 4 рдкреВрд░реНрдг рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рддрд╣рдд рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдХреЛ рджреЛ рд╡рд┐рдзрд╛рдирд╕рднрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ - System.Design рдФрд░ System.Drawing.Designред

рдХрд╛рд╢, рдЖрдк TabControl рдореЗрдВ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдЖрдкрдХреЛ TabCageCollection рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ TabControl рдХреЗ рдЕрдВрджрд░ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХрдХреНрд╖рд╛ рдХреЛ рд╕реНрд╡рдпрдВ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╣рдо рдмрджрд▓реЗ рдореЗрдВ рдЗрд╕рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗред рд╣рд╛рдВ, рдФрд░ рдореИрдВ рдЖрдкрдХреЛ рддреБрд░рдВрдд рдЪреЗрддрд╛рд╡рдиреА рджреВрдВрдЧрд╛ - рдХреЛрдб рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓ рдХреЗ рдЕрдВрджрд░ рдХреЛрдИ рд▓рд╛рдЗрди рдирд╣реАрдВ рдереА "System.Windows.Forms?" рдХреЛрдб рдХреЗ рд╕рд╛рде, рдЗрд╕рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рдореЗрдВ рдорд╛рдирдХ рдШрдЯрдХреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдЙрдкрд╕рд░реНрдЧ "System.Windows.Forms" рдХреЗ рд╕рд╛рде рдЖрддреА рд╣реИред TabControl рдФрд░ TabPage рдХрд╕реНрдЯрдо рдУрд╡рд░рд░рд╛рдЗрдб рдкреНрд░рдХрд╛рд░ рд╣реИрдВред
 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Drawing.Design; using System.ComponentModel.Design; namespace WindowsFormsApplication1 { public class TabControl : System.Windows.Forms.TabControl { //    . public new class TabPageCollection : System.Windows.Forms.TabControl.TabPageCollection { public TabPageCollection(TabControl owner) : base(owner) { } } public TabControl() { } private TabPageCollection mTabCollection = null; //      ,    Editor   . [Editor(typeof(TabPageCollectionEditor), typeof(UITypeEditor))] public new System.Windows.Forms.TabControl.TabPageCollection TabPages { get { if (mTabCollection == null) mTabCollection = new TabPageCollection(this); return mTabCollection; } } } //     .      . public class TabPageCollectionEditor : System.ComponentModel.Design.CollectionEditor { public TabPageCollectionEditor(Type type) : base(type) { } protected override Type CreateCollectionItemType() { return typeof(TabPage); } protected override Type[] CreateNewItemTypes() { return new Type[] { typeof(TabPage) }; } } } 


рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЯреИрдмрдкреЗрдЬ:
 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WindowsFormsApplication1 { public class TabPage : System.Windows.Forms.TabPage { public TabPage() { } } } 


рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИред рдЕрдЧрд▓реЗ рдЪрд░рдг рдкрд░ рдЬрд╛рдПрдВред

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдЯреИрдм рдЬреЛрдбрд╝рдирд╛ред
рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХреЗ рд╕реЗ рдЧрдП: рдЯреИрдмрдХрдВрдЯреНрд░реЛрд▓ рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ "+" рд╢реАрд░реНрд╖рдХ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЦрд╛рд▓реА рдЯреИрдм рд╣реИред рдЬрдм рдЗрд╕реЗ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЯреИрдм рдЬреЛрдбрд╝рдиреЗ рд╡рд╛рд▓реА рдШрдЯрдирд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, TabPageCollection рдкреНрд░рдХрд╛рд░ рдореЗрдВ, рд╣рдо Clear Method рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ - рдЯреИрдм рдХреНрд▓рд┐рдпрд░ рдХрд░рддреЗ рд╕рдордп, рд╣рдореЗрдВ "+" рдЯреИрдм рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
 public override void Clear() { System.Windows.Forms.TabPage page = null; if (this.ContainsKey(TabControl.KeyPageAllowAddName)) page = this[TabControl.KeyPageAllowAddName]; base.Clear(); if (page != null) this.Add(page); } 


TabControl рдХреЛрдб рдореЗрдВ, рд╣рдо рдПрдХ рд╡реИрд░рд┐рдПрдмрд▓ рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЯреИрдм "+" рдХреЗ рдирд╛рдо рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИред
 public static string KeyPageAllowAddName = "___page_allow_to_add_name___"; 


рд╣рдо рдШрдЯрдХ рдХреЗ AllowUserToAddTab рд╕рдВрдкрддреНрддрд┐ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЖрдк рдирдП рдСрдкрд░реЗрд╢рди рдореЛрдб рдХреЛ рд╕рдХреНрд╖рдо / рдЕрдХреНрд╖рдо рдХрд░ рд╕рдХреЗрдВред рдЦреИрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЯреИрдм рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреА рд╣реИ рдФрд░, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЗрд╕реЗ рдЬреЛрдбрд╝рддрд╛ / рд╣рдЯрд╛рддрд╛ рд╣реИред

 public TabControl() { this.Enter += new EventHandler((sender, e) => { CheckAllowUserToAddTab(); }); this.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(TabControl_Selecting); } private bool mAllowUserToAddTab = false; [Browsable(true), Description("   .   +,       OnUserAddedTab."), Category("Action")] public virtual bool AllowUserToAddTab { get { return mAllowUserToAddTab; } set { mAllowUserToAddTab = value; } } void CheckAllowUserToAddTab() { if (mAllowUserToAddTab) { System.Windows.Forms.TabPage page_allow_to_add = TabPages[KeyPageAllowAddName]; if (mAllowUserToAddTab) { if (page_allow_to_add == null) { page_allow_to_add = new TabPage(); page_allow_to_add.Name = KeyPageAllowAddName; page_allow_to_add.Text = "+"; TabPages.Insert(0, page_allow_to_add); } } else { if (page_allow_to_add != null) TabPages.Remove(page_allow_to_add); } } } 


рд╣рдо рдЯреИрдм рдЯреИрдм рдЗрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ:
 public delegate bool TabPageAdding(TabControl control, TabPage page); 


рдЯреИрдм рдЬреЛрдбрд╝рдиреЗ рдХреА рдШрдЯрдирд╛ рдФрд░ рд╡рд┐рдзрд┐:
 public event TabPageAdding PageAdding; void TabControl_Selecting(object sender, System.Windows.Forms.TabControlCancelEventArgs e) { if (TabPages.Count > 0 && e.TabPage.Name == KeyPageAllowAddName) { e.Cancel = true; TabPage page = new TabPage(); if (PageAdding != null) foreach (TabPageAdding _delegate in PageAdding.GetInvocationList()) { try { if (!_delegate.Invoke(this, page)) return; } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } } TabPages.Add(page); } } 

рдРрдб рдИрд╡реЗрдВрдЯ рдХреЗ рд╕рднреА рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░реНрд╕ рдХреА рд╕реВрдЪреА рдХреЛ рд╕реНрдХреНрд░реЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдЙрдирдореЗрдВ рд╕реЗ рдХрдо рд╕реЗ рдХрдо рдХреЛрдИ рдЧрд▓рдд рд░рд┐рдЯрд░реНрди рджреЗрддрд╛ рд╣реИ, рддреЛ рдРрдб рд░рджреНрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

TabPageCollectionEditor рд╡рд░реНрдЧ рдореЗрдВ, рдЖрдкрдХреЛ GetItems рдФрд░ SetItems рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЙрдиреНрд╣реЗрдВ рд╕рдВрдкрд╛рджрдХ рд╕реЗ рдШрдЯрдХ рддрдХ рдЯреИрдм рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдФрд░ "+" рдЯреИрдм рдХреЛ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
 protected override object[] GetItems(object editValue) { try { object[] values = base.GetItems(editValue); List<object> values2 = new List<object>(); foreach (var element in values) { if (element.GetType() == typeof(TabPage)) { TabPage tp = (TabPage)element; if (tp.Name == TabControl.KeyPageAllowAddName) continue; } values2.Add(element); } return values2.ToArray(); } catch (Exception ex){System.Windows.Forms.MessageBox.Show(ex.Message);} return base.GetItems(editValue); } protected override object SetItems(object editValue, object[] value) { try { List<object> values2 = new List<object>(); foreach (var element in value) { if (element.GetType() == typeof(TabPage)) { TabPage tp = (TabPage)element; if (tp.Name == TabControl.KeyPageAllowAddName) continue; } values2.Add(element); } return base.SetItems(editValue, values2.ToArray()); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } return base.SetItems(editValue, value); } 


рдлрд┐рд░ рд╣рдордиреЗ рдПрдХ рдФрд░ рдЕрд╡рд╕рд░ рдЬреЛрдбрд╝рд╛: рдЯреИрдм рдХреЗ рдкрд╣рд▓реЗ рдЙрджреНрдШрд╛рдЯрди рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛ (рдкрд╣рд▓реА рдмрд╛рд░ рдЯреИрдм рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдлреЙрд░реНрдо рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛)

рдпрд╣рд╛рдВ рдПрдХ рдФрд░ рдИрд╡реЗрдВрдЯ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ, рд╕реВрдЪреА рдФрд░ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╕рд┐рд▓реЗрдХреНрдЯреЗрдбрдЗрдВрдбреЗрдХреНрд╕рдЪреЗрдВрдЬ / рдПрдВрдЯрд░ / рдХреНрд▓рд┐рдХ:
 public TabControl() { this.Enter += new EventHandler(TabControl_PageEvent); this.Click += new EventHandler(TabControl_PageEvent); this.SelectedIndexChanged += new EventHandler(TabControl_PageEvent); this.Enter += new EventHandler((sender, e) => { CheckAllowUserToAddTab(); }); this.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(TabControl_Selecting); } .... private Dictionary<System.Windows.Forms.TabPage, bool> mLoaded = new Dictionary<System.Windows.Forms.TabPage, bool>(); public delegate void TabPageLoadedEventHandler(TabControl control, System.Windows.Forms.TabPage page); public event TabPageLoadedEventHandler PageLoad; void TabControl_PageEvent(object sender, EventArgs e) { if (this.SelectedTab != null && !mLoaded.ContainsKey(this.SelectedTab)) { mLoaded.Add(this.SelectedTab, true); if (PageLoad != null) PageLoad(this, this.SelectedTab); } } 


рдмреЗрд╢рдХ, рдпрд╣рд╛рдВ рдЕрднреА рднреА рдмрд╣реБрдд рдХреБрдЫ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, TabPageControlCollection рдореЗрдВ рдЖрдк рдЯреИрдм рдХреА рд╕рдВрдЦреНрдпрд╛ ("+" рдЯреИрдм рдХреЛ рдмрд╛рд╣рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП) рдХреЛ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реАрдХреЛрдВ рдХреЛ рдЕрдзрд┐рднрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЭреЗ рдШрдЯрдХ рдХреЗ рд░реЗрдВрдбрд░рд┐рдВрдЧ рддрд░реАрдХреЛрдВ рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ + рдЯреИрдм рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛, рдЗрд╕рд▓рд┐рдП рд╡рдХреНрд░ рдХреЗ рд▓рд┐рдП рд░рд╛рд╕реНрддреЗ рдХреЛ рджреЛрд╖ рди рджреЗрдВред DevExpress рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ IMHO, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП - рдХрд░реЗрдВрдЧреЗред

Source: https://habr.com/ru/post/In139027/


All Articles