2015-06-26 4 views
0

Got TableLayoutPanel с 1 столбцом и N строками , необходимые для ячеек, можно изменять с помощью somthing как Splitter-компонента между ячейками. без использования SplitContainer.Как сделать TableLayoutPanel с изменяемыми размерами ячейками, например, с помощью Splitter

Может быть любая другая идея без TableLayoutPanel?

+1

Возможно, вам лучше всего использовать один столбец 'DataGridView' с параметром AllowUserToResizeRows' равным true и поворот заголовков строк и столбцов. – Anthony

+0

Только для 1 столбца может быть более удобной панель flowlayoutpan (flowdirection topdown и wrapcontents = false), и сплиттер должен будет только изменять размеры элементов управления, после этого будет выполняться поток. Как это бывает, уже существует проект, который реализует расписание потока с разветвителями: http://www.codeproject.com/Articles/43158/MultisplitContainer-A-FlowlayoutPanel-Providing-Si. Не пробовал, но это может быть то, что вам нужно. –

ответ

4

Это действительно зависит от того, что вы хотите сделать с ним: а DataGridView приносит с собой интерактивность, но его клетки не являются ни управления, ни контейнеры ..

Вы можете попробовать, если это TableLayoutPanel подкласс делает то, что вы хотите:

public partial class SplitTablePanel : TableLayoutPanel 
{ 
    public int SplitterSize { get; set; } 

    int sizingRow = -1; 
    int currentRow = -1; 
    Point mdown = Point.Empty; 
    int oldHeight = -1; 
    bool isNormal = false; 
    List<RectangleF> TlpRows = new List<RectangleF>(); 
    int[] rowHeights = new int[0]; 

    public SplitTablePanel() 
    { 
     InitializeComponent(); 
     this.MouseDown += SplitTablePanel_MouseDown; 
     this.MouseMove += SplitTablePanel_MouseMove; 
     this.MouseUp += SplitTablePanel_MouseUp; 
     this.MouseLeave += SplitTablePanel_MouseLeave; 
     SplitterSize = 6; 
    } 

    void SplitTablePanel_MouseLeave(object sender, EventArgs e) 
    { 
     Cursor = Cursors.Default; 
    } 


    void SplitTablePanel_MouseUp(object sender, MouseEventArgs e) 
    { 
     getRowRectangles(SplitterSize); 
    } 

    void SplitTablePanel_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (!isNormal) nomalizeRowStyles(); 
     if (TlpRows.Count <= 0) getRowRectangles(SplitterSize); 
     if (rowHeights.Length <= 0) rowHeights = GetRowHeights(); 

     if (e.Button == System.Windows.Forms.MouseButtons.Left) 
     { 
      if (sizingRow < 0) return; 
      int newHeight = oldHeight + e.Y - mdown.Y; 
      sizeRow(sizingRow, newHeight); 
     } 
     else 
     { 
      currentRow = -1; 
      for (int i = 0; i < TlpRows.Count; i++) 
       if (TlpRows[i].Contains(e.Location)) { currentRow = i; break;} 
      Cursor = currentRow >= 0 ? Cursors.SizeNS : Cursors.Default; 
     } 
    } 

    void SplitTablePanel_MouseDown(object sender, MouseEventArgs e) 
    { 
     mdown = Point.Empty; 
     sizingRow = -1; 
     if (currentRow < 0) return; 
     sizingRow = currentRow; 
     oldHeight = rowHeights[sizingRow]; 
     mdown = e.Location; 
    } 


    void getRowRectangles(float size) 
    { // get a list of mouse sensitive rectangles 
     float sz = size/2f; 
     float y = 0f; 
     int w = ClientSize.Width; 
     int[] rw = GetRowHeights(); 

     TlpRows.Clear(); 
     for (int i = 0; i < rw.Length - 1; i++) 
     { 
      y += rw[i]; 
      TlpRows.Add(new RectangleF(0, y - sz, w, size)); 
     } 

    } 

    void sizeRow(int row, int newHeight) 
    { // change the height of one row 
     if (newHeight == 0) return; 
     if (sizingRow < 0) return; 
     SuspendLayout(); 
     rowHeights = GetRowHeights(); 
     if (sizingRow >= rowHeights.Length) return; 

     if (newHeight > 0) 
      RowStyles[sizingRow] = new RowStyle(SizeType.Absolute, newHeight); 
     ResumeLayout(); 
     rowHeights = GetRowHeights(); 
     getRowRectangles(SplitterSize); 
    } 

    void nomalizeRowStyles() 
    { // set all rows to absolute and the last one to percent=100! 
     if (rowHeights.Length <= 0) return; 
     rowHeights = GetRowHeights(); 
     RowStyles.Clear(); 
     for (int i = 0; i < RowCount - 1; i++) 
     { 
      RowStyle cs = new RowStyle(SizeType.Absolute, rowHeights[i]); 
      RowStyles.Add(cs); 
     } 
     RowStyles.Add (new RowStyle(SizeType.Percent, 100)); 
     isNormal = true; 
    } 
} 
} 
2

в дополнение к большой ответ TAW «s, здесь Еще один подход, который позволяет изменять размер строк и столбцов, а также и закрывает небольшую ошибку, которая появляется, если управление изменяется (-> в коде TAW в разделительные прямоугольниками тоже не изменяются).

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Windows.Forms; 

namespace SomeNameSpace.Controls 
{ 
    public partial class SplitTableLayoutPanel : TableLayoutPanel 
    { 
     public int SplitterSize { get; set; } 

     int sizingRow = -1; 
     int currentRow = -1; 
     Point mdown = Point.Empty; 
     int oldHeight = -1; 
     bool isNormalRow = false; 
     List<RectangleF> tlpRows = new List<RectangleF>(); 
     int[] rowHeights = new int[0]; 

     int sizingCol = -1; 
     int currentCol = -1; 
     int oldWidth = -1; 
     bool isNormalCol = false; 
     List<RectangleF> tlpCols = new List<RectangleF>(); 
     int[] colWidths = new int[0]; 

     public SplitTableLayoutPanel() 
     { 
      InitializeComponent(); 
      this.MouseDown += SplitTablePanel_MouseDown; 
      this.MouseMove += SplitTablePanel_MouseMove; 
      this.MouseUp += SplitTablePanel_MouseUp; 
      this.MouseLeave += SplitTablePanel_MouseLeave; 
      this.Resize += SplitTablePanel_Resize; 
      SplitterSize = 6; 
     } 

     void SplitTablePanel_Resize(object sender, EventArgs e) 
     { 
      getRowRectangles(SplitterSize); 
      getColRectangles(SplitterSize); 
     } 
     void SplitTablePanel_MouseLeave(object sender, EventArgs e) 
     { 
      Cursor = Cursors.Default; 
     } 


     void SplitTablePanel_MouseUp(object sender, MouseEventArgs e) 
     { 
      getRowRectangles(SplitterSize); 
      getColRectangles(SplitterSize); 
     } 

     void SplitTablePanel_MouseMove(object sender, MouseEventArgs e) 
     { 
      bool r = rowMove(sender, e); 
      bool c = colMove(sender, e);  

      if (r && !c) 
       Cursor = Cursors.SizeNS; 
      else if (!r && c) 
       Cursor = Cursors.SizeWE; 
      else if (r && c) 
       Cursor = Cursors.SizeAll; 
      else 
       Cursor = Cursors.Default; 
     } 

     bool rowMove(object sender, MouseEventArgs e) 
     { 
      bool isMove = false; 
      if (!isNormalRow) nomalizeRowStyles(); 
      if (tlpRows.Count <= 0) getRowRectangles(SplitterSize); 
      if (rowHeights.Length <= 0) rowHeights = GetRowHeights(); 

      if (e.Button == System.Windows.Forms.MouseButtons.Left) 
      { 
       if (sizingRow < 0) return false; 
       int newHeight = oldHeight + e.Y - mdown.Y; 
       sizeRow(sizingRow, newHeight); 
       isMove = true; 
      } 
      else 
      { 
       currentRow = -1; 
       for (int i = 0; i < tlpRows.Count; i++) 
       if (tlpRows[i].Contains(e.Location)) 
       { 
        currentRow = i; 
        isMove = true; 
        break; 
       } 
      } 
      return isMove; 
     } 

     bool colMove(object sender, MouseEventArgs e) 
     { 
      bool isMove = false; 
      if (!isNormalCol) nomalizeColStyles(); 
      if (tlpCols.Count <= 0) getColRectangles(SplitterSize); 
      if (colWidths.Length <= 0) colWidths = GetColumnWidths(); 

      if (e.Button == System.Windows.Forms.MouseButtons.Left) 
      { 
       if (sizingCol < 0) return false; 
       int newWidth = oldWidth + e.X - mdown.X; 
       sizeCol(sizingCol, newWidth); 
       isMove = true; 
      } 
      else 
      { 
       currentCol = -1; 
       for (int i = 0; i < tlpCols.Count; i++) 
       if (tlpCols[i].Contains(e.Location)) 
       { 
        currentCol = i; 
        isMove = true; 
        break; 
       } 
      } 
      return isMove; 
     } 

     void SplitTablePanel_MouseDown(object sender, MouseEventArgs e) 
     { 
      mdown = Point.Empty; 
      rowDown(); 
      colDown(); 
      mdown = e.Location; 
     } 

     void rowDown() 
     { 
      sizingRow = -1; 
      if (currentRow < 0) return; 
      sizingRow = currentRow; 
      oldHeight = rowHeights[sizingRow]; 
     } 

     void colDown() 
     { 
      sizingCol = -1; 
      if (currentCol < 0) return; 
      sizingCol = currentCol; 
      oldWidth = colWidths[sizingCol]; 
     } 


     void getRowRectangles(float size) 
     { // get a list of mouse sensitive rectangles 
      float sz = size/2f; 
      float y = 0f; 
      int w = ClientSize.Width; 
      int[] rw = GetRowHeights(); 

      tlpRows.Clear(); 
      for (int i = 0; i < rw.Length - 1; i++) 
      { 
       y += rw[i]; 
       tlpRows.Add(new RectangleF(0, y - sz, w, size)); 
      } 

     } 

     void getColRectangles(float size) 
     { // get a list of mouse sensitive rectangles 
      float sz = size/2f; 
      float x = 0f; 
      int h = ClientSize.Height; 
      int[] rw = GetColumnWidths(); 

      tlpCols.Clear(); 
      for (int i = 0; i < rw.Length - 1; i++) 
      { 
       x += rw[i]; 
       tlpCols.Add(new RectangleF(x - sz, 0, size, h)); 
      } 

     } 

     void sizeRow(int row, int newHeight) 
     { // change the height of one row 
      if (newHeight == 0) return; 
      if (sizingRow < 0) return; 
      SuspendLayout(); 
      rowHeights = GetRowHeights(); 
      if (sizingRow >= rowHeights.Length) return; 

      if (newHeight > 0) 
       RowStyles[sizingRow] = new RowStyle(SizeType.Absolute, newHeight); 
      ResumeLayout(); 
      rowHeights = GetRowHeights(); 
      getRowRectangles(SplitterSize); 
     } 

     void sizeCol(int col, int newWidth) 
     { // change the height of one row 
      if (newWidth == 0) return; 
      if (sizingCol < 0) return; 
      SuspendLayout(); 
      colWidths = GetColumnWidths(); 
      if (sizingCol >= colWidths.Length) return; 

      if (newWidth > 0) 
       ColumnStyles[sizingCol] = new ColumnStyle(SizeType.Absolute, newWidth); 
      ResumeLayout(); 
      colWidths = GetColumnWidths(); 
      getColRectangles(SplitterSize); 
     } 

     void nomalizeRowStyles() 
     { // set all rows to absolute and the last one to percent=100! 
      if (rowHeights.Length <= 0) return; 
      rowHeights = GetRowHeights(); 
      RowStyles.Clear(); 
      for (int i = 0; i < RowCount - 1; i++) 
      { 
       RowStyle cs = new RowStyle(SizeType.Absolute, rowHeights[i]); 
       RowStyles.Add(cs); 
      } 
      RowStyles.Add (new RowStyle(SizeType.Percent, 100)); 
      isNormalRow = true; 
     } 

     void nomalizeColStyles() 
     { // set all rows to absolute and the last one to percent=100! 
      if (colWidths.Length <= 0) return; 
      colWidths = GetColumnWidths(); 
      ColumnStyles.Clear(); 
      for (int i = 0; i < ColumnCount - 1; i++) 
      { 
       ColumnStyle cs = new ColumnStyle(SizeType.Absolute, colWidths[i]); 
       ColumnStyles.Add(cs); 
      } 
      ColumnStyles.Add (new ColumnStyle(SizeType.Percent, 100)); 
      isNormalCol = true; 
     } 
    } 
}