2010-12-04 6 views
8

क्या आईई या फ़ायरफ़ॉक्स जैसे रन-टाइम पर WinForms TabControl में टैब को पुन: व्यवस्थित करना संभव है?क्या WinForms टैब नियंत्रण आईई या फ़ायरफ़ॉक्स जैसे टैब रीडरिंग करने में सक्षम हो सकता है?

Links like this मुझे बहुत उम्मीद नहीं है।

उत्तर

9

निश्चित रूप से, यह संभव है! आप समाधान को अधिक जटिल बनाने की कोशिश कर रहे हैं। अनिवार्य रूप से, आपको बस मानक TabControl उप-वर्ग करना है और माउस ईवेंट हैंडलर में कुछ तर्क जोड़ें। आपको केवल यह जांचने की आवश्यकता होगी कि उपयोगकर्ता वर्तमान में किस प्रारूप को खींच रहा है और इसे TabPages संग्रह में पुन: व्यवस्थित कर रहा है।

1

पुनर्व्यवस्था TabPages और ड्रॉप - लुडविग बी द्वारा:

वहाँ पूर्ण समाधान उपलब्ध ऑनलाइन के एक जोड़े हैं
मैं solution मूल रूप @Cody ग्रे द्वारा पोस्ट मैं ज्यादातर क्या चाहता हो पाया द्वारा http://dotnetrix.co.uk/tabcontrol.htm#tip7

 private void tc_MouseDown(object sender, MouseEventArgs e) 
     { 
      // store clicked tab 
      TabControl tc = (TabControl)sender; 
      int hover_index = this.getHoverTabIndex(tc); 
      if (hover_index >= 0) { tc.Tag = tc.TabPages[hover_index]; } 
     } 
     private void tc_MouseUp(object sender, MouseEventArgs e) 
     { 
      // clear stored tab 
      TabControl tc = (TabControl)sender; 
      tc.Tag = null; 
     } 
     private void tc_MouseMove(object sender, MouseEventArgs e) 
     {   
      // mouse button down? tab was clicked? 
      TabControl tc = (TabControl)sender; 
      if ((e.Button != MouseButtons.Left) || (tc.Tag == null)) return; 
      TabPage clickedTab = (TabPage)tc.Tag; 
      int clicked_index = tc.TabPages.IndexOf(clickedTab); 

      // start drag n drop 
      tc.DoDragDrop(clickedTab, DragDropEffects.All); 
     } 
     private void tc_DragOver(object sender, DragEventArgs e) 
     { 
      TabControl tc = (TabControl)sender; 

      // a tab is draged? 
      if (e.Data.GetData(typeof(TabPage)) == null) return; 
      TabPage dragTab = (TabPage)e.Data.GetData(typeof(TabPage)); 
      int dragTab_index = tc.TabPages.IndexOf(dragTab); 

      // hover over a tab? 
      int hoverTab_index = this.getHoverTabIndex(tc); 
      if (hoverTab_index < 0) { e.Effect = DragDropEffects.None; return; } 
      TabPage hoverTab = tc.TabPages[hoverTab_index]; 
      e.Effect = DragDropEffects.Move; 

      // start of drag? 
      if (dragTab == hoverTab) return; 

      // swap dragTab & hoverTab - avoids toggeling 
      Rectangle dragTabRect = tc.GetTabRect(dragTab_index); 
      Rectangle hoverTabRect = tc.GetTabRect(hoverTab_index); 

      if (dragTabRect.Width < hoverTabRect.Width) 
      { 
       Point tcLocation = tc.PointToScreen(tc.Location); 

       if (dragTab_index < hoverTab_index) 
       { 
        if ((e.X - tcLocation.X) > ((hoverTabRect.X + hoverTabRect.Width) - dragTabRect.Width)) 
         this.swapTabPages(tc, dragTab, hoverTab); 
       } 
       else if (dragTab_index > hoverTab_index) 
       { 
        if ((e.X - tcLocation.X) < (hoverTabRect.X + dragTabRect.Width)) 
         this.swapTabPages(tc, dragTab, hoverTab); 
       } 
      } 
      else this.swapTabPages(tc, dragTab, hoverTab); 

      // select new pos of dragTab 
      tc.SelectedIndex = tc.TabPages.IndexOf(dragTab); 
     } 

     private int getHoverTabIndex(TabControl tc) 
     { 
      for (int i = 0; i < tc.TabPages.Count; i++) 
      { 
       if (tc.GetTabRect(i).Contains(tc.PointToClient(Cursor.Position))) 
        return i; 
      } 

      return -1; 
     } 

     private void swapTabPages(TabControl tc, TabPage src, TabPage dst) 
     { 
      int index_src = tc.TabPages.IndexOf(src); 
      int index_dst = tc.TabPages.IndexOf(dst); 
      tc.TabPages[index_dst] = src; 
      tc.TabPages[index_src] = dst; 
      tc.Refresh(); 
     } 
+1

हाँ, मैं पहले से ही अपने उत्तर में उसी नमूने से जुड़ा हुआ हूं। कई महीने पहले। –

6

प्रेरित है, लेकिन मैं जरूरत नहीं देखा था यह इतनी जटिल होने के लिए।

यह मेरा सरलीकरण, TabControl से पाने द्वारा कार्यान्वित है:

public class DraggableTabControl : TabControl 
{ 
    private TabPage m_DraggedTab; 

    public DraggableTabControl() 
    { 
     MouseDown += OnMouseDown; 
     MouseMove += OnMouseMove; 
    } 

    private void OnMouseDown(object sender, MouseEventArgs e) 
    { 
     m_DraggedTab = TabAt(e.Location); 
    } 

    private void OnMouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.Button != MouseButtons.Left || m_DraggedTab == null) 
     { 
      return; 
     } 

     TabPage tab = TabAt(e.Location); 

     if (tab == null || tab == m_DraggedTab) 
     { 
      return; 
     } 

     Swap(m_DraggedTab, tab); 
     SelectedTab = m_DraggedTab; 
    } 

    private TabPage TabAt(Point position) 
    { 
     int count = TabCount; 

     for (int i = 0; i < count; i++) 
     { 
      if (GetTabRect(i).Contains(position)) 
      { 
       return TabPages[i]; 
      } 
     } 

     return null; 
    } 

    private void Swap(TabPage a, TabPage b) 
    { 
     int i = TabPages.IndexOf(a); 
     int j = TabPages.IndexOf(b); 
     TabPages[i] = b; 
     TabPages[j] = a; 
    } 
} 

ड्रैग और ड्रॉप एपीआई वास्तव में बहुत कम से कम, अलग नियंत्रण अलग अनुप्रयोगों के बीच सामान खींच लिए हैं, या। इस मामले में उनका उपयोग करना अधिक है।

सुनिश्चित करें कि आप कोडी के जवाब को भी ऊपर उठाएं यदि आप मेरा उत्थान करते हैं, क्योंकि यह उसके आधार पर है।

+0

अच्छा काम! यह वास्तव में एक सरल समाधान है। –

1

मैंने जैकब स्टेनली का जवाब थोड़ा बढ़ाया। इस तरह स्वैपिंग अक्सर नहीं होती है। यह विशेष रूप से विभिन्न आकारों के टैब के लिए सहायक होता है, जिस स्थिति में पिछले समाधान को खींचते समय अक्सर स्वैप किया जाएगा।

उपयोगकर्ता अनुभव में अंतर यह है कि आपको वास्तव में टैब को स्थानांतरित करने के लिए थोड़ा और खींचना होगा। लेकिन यह ब्राउज़र में टैब रीडरिंग के समान है।

इसके अलावा मैंने डबल-बफरिंग ड्रैगिंग और सक्षम करते समय एक हाथ कर्सर जोड़ा।

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace Controls 
{ 
    public class DraggableTabControl : TabControl 
    { 
     private TabPage draggedTab; 

     public DraggableTabControl() 
     { 
      this.MouseDown += OnMouseDown; 
      this.MouseMove += OnMouseMove; 
      this.Leave += new System.EventHandler(this.DraggableTabControl_Leave); 

      this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); 
     } 

     private void OnMouseDown(object sender, MouseEventArgs e) 
     { 
      draggedTab = TabAt(e.Location); 
     } 

     private void OnMouseMove(object sender, MouseEventArgs e) 
     { 
      if (e.Button != MouseButtons.Left || draggedTab == null) 
      { 
       this.Cursor = this.DefaultCursor; 
       draggedTab = null; 
       return; 
      } 

      int index = TabPages.IndexOf(draggedTab);   
      int nextIndex = index + 1; 
      int prevIndex = index - 1; 

      int minXForNext = int.MaxValue; 
      int maxXForPrev = int.MinValue; 

      var tabRect = GetTabRect(index); 

      if (nextIndex < TabPages.Count) 
      { 
       var nextTabRect = GetTabRect(nextIndex); 
       minXForNext = tabRect.Left + nextTabRect.Width; 
      } 

      if (prevIndex >= 0) 
      { 
       var prevTabRect = GetTabRect(prevIndex); 
       maxXForPrev = prevTabRect.Left + tabRect.Width; 
      } 

      this.Cursor = Cursors.Hand; 

      if (e.Location.X > maxXForPrev && e.Location.X < minXForNext) 
      { 
       return; 
      } 

      TabPage tab = TabAt(e.Location); 

      if (tab == null || tab == draggedTab) 
      { 
       return; 
      } 

      Swap(draggedTab, tab); 
      SelectedTab = draggedTab; 
     } 

     private TabPage TabAt(Point position) 
     { 
      int count = TabCount; 

      for (int i = 0; i < count; i++) 
      { 
       if (GetTabRect(i).Contains(position)) 
       { 
        return TabPages[i]; 
       } 
      } 

      return null; 
     } 

     private void Swap(TabPage a, TabPage b) 
     { 
      int i = TabPages.IndexOf(a); 
      int j = TabPages.IndexOf(b); 

      TabPages[i] = b; 
      TabPages[j] = a; 
     } 

     private void DraggableTabControl_Leave(object sender, EventArgs e) 
     { 
      this.Cursor = this.DefaultCursor; 
      draggedTab = null; 
     } 
    } 
} 
संबंधित मुद्दे