Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - C#: Aiuto creazione controllo personalizzato a colonne
Forum - C# / VB.NET - C#: Aiuto creazione controllo personalizzato a colonne

Avatar
Sevenjeak (Normal User)
Pro


Messaggi: 84
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 9:46
Martedì, 14/03/2017
Salve,

Sto creando, il questi giorni, un controllo posizionato nella parte superiore, simulando una toolbar, contenente dentro dei panelli, simulando delle colonne.

So che per fare una struttura a colonne potrei utilizzare il TableLayoutPane, ma avrei la necessità di far inserire più elementi in ogni colonna, cosa che questo controllo non fa.

Fino ad ora il codice del componente è questo:

Codice sorgente - presumibilmente VB.NET

  1. public class xComponent : ContainerControl
  2. private List<Panel> columns = null;
  3.         private BorderStyle columnsBorderStyle = BorderStyle.None;
  4.  
  5.         public BorderStyle ColumnsBorderStyle
  6.         {
  7.             get
  8.             {
  9.                 return columnsBorderStyle;
  10.             }set
  11.             {
  12.                 columns.ForEach(delegate (Panel element)
  13.                 {
  14.                     element.BorderStyle = value;
  15.                 });
  16.  
  17.                 columnsBorderStyle = value;
  18.             }
  19.         }
  20.  
  21.         public xComponent(int num_columns, params int[] percentSize)
  22.         {
  23.             Dock = DockStyle.Top;
  24.             BackColor = Color.FromArgb(230, 230, 230);
  25.             Size = new Size(968, 30);
  26.          
  27.             columns = new List<Panel>();
  28.  
  29.             // Add columns into the control
  30.             for (int i = 0; i < num_columns; i++)
  31.             {
  32.                 columns.Add(new Panel());
  33.                 columns[i].Height = Height;
  34.                 Controls.Add(columns[i]);
  35.             }
  36.  
  37.             positionColumns(num_columns, percentSize);
  38.         }
  39.  
  40.         public Panel Column(int index)
  41.         {
  42.             return columns[index];
  43.         }
  44.  
  45.         private void positionColumns(int num_columns, int[] percentSize)
  46.         {
  47.             for (int i = 0; i < num_columns; i++)
  48.             {
  49.                 columns[i].Left = (i > 0) ? columns[i - 1].Width : 0;
  50.                 columns[i].Width = (percentSize.Length == 0) ? Width / num_columns : (Width * percentSize[i]) / 100;
  51.             }
  52.         }
  53.  
  54.         protected override void OnPaint(PaintEventArgs e)
  55.         {
  56.             base.OnPaint(e);
  57.         }
  58.     }



Creato e aggiunto nel form in questo modo:

Codice sorgente - presumibilmente C# / VB.NET

  1. xComponent xc = new xComponent(3);
  2. xc.ColumnsBorderStyle = BorderStyle.FixedSingle;
  3. Controls.Add(xc);



Il costruttore, dichiarato cosi, dovrebbe creare una toolbar con tre colonne, posizionando le tre colonne in modo che occupino tutte e tre lo stesso spazio, ma sè, nel costruttore, aggiungevo altri tre parametri questi ultimi deferiranno la dimensione in percentuale occupata dalle colonne.

I problemi sono che:

1) Non mi vengono aggiunte più di due colonne, eppure controllando la lunghezza dell'array corrisponde al numero di elementi ( colonne ) che voglio, come mai ciò?

2) In ogni caso, la dimensione delle colonne non è corretta, sbaglio qualche calcolo, se se come dovrà essere?

Ultima modifica effettuata da Sevenjeak il 14/03/2017 alle 9:48


Programmando si impara..
PM Quote
Avatar
Thejuster (Member)
Guru^2


Messaggi: 1704
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 14:53
Martedì, 14/03/2017
Il codice sbagliato è sicuramente il tuo calcolo.

Ho eliminato un pò di roba inutile.

PS:
Ricorda che all'inizio dopo che il controllo viene disegnato, viene automaticamente innescato
il metodo resize per portare il Form ad una certa dimensione specificata nell'IDE
quindi è sempre Fondamentale! eseguire un override anche sul metodo resize
e ridisegnare il controlo non diventa un optional ma un obbligo.

Ho eliminato anche il parametro percent_size perché se il controllo è in Dock
è praticamente inutile avere una percentuale relativa alla dimensione.

Ti mostro velocemente la mia correzione poi puoi aggiustarla come meglio ti pare

Codice sorgente - presumibilmente C#

  1. public partial class xComponent : ContainerControl
  2.     {
  3.  
  4.         public xComponent()
  5.         {
  6.             this.columnsBorderStyle = BorderStyle.FixedSingle;
  7.         }
  8.    
  9.         private List<Panel> columns = null;
  10.         private BorderStyle columnsBorderStyle = BorderStyle.None;
  11.  
  12.      
  13.  
  14.         public xComponent(int num_columns, params int[] percentSize)
  15.         {
  16.             Dock = DockStyle.Top;
  17.             BackColor = Color.FromArgb(230, 230, 230);
  18.             Size = new Size(968, 30);
  19.          
  20.             columns = new List<Panel>();
  21.  
  22.             // Add columns into the control
  23.             for (int i = 0; i < num_columns; i++)
  24.             {
  25.                 columns.Add(new Panel() { BorderStyle = BorderStyle.FixedSingle});
  26.                 columns[i].Height = Height;
  27.                 Controls.Add(columns[i]);
  28.             }
  29.  
  30.             positionColumns(num_columns/*, percentSize*/);
  31.         }
  32.  
  33.         public Panel Column(int index)
  34.         {
  35.             return columns[index];
  36.         }
  37.  
  38.         private void positionColumns(int num_columns/*, int[] percentSize*/)
  39.         {
  40.  
  41.              //Tuo Calcolo
  42.             /*for (int i = 0; i < num_columns; i++)
  43.             {
  44.                 columns[i].Left = (i > 0) ? columns[i - 1].Width : 0;
  45.                 columns[i].Width = (percentSize.Length == 0) ? Width / num_columns : (Width * percentSize[i]) / 100;
  46.             }*/
  47.  
  48.             //Mio Calcolo
  49.             int step = Width / num_columns;
  50.  
  51.             for (int i = 0; i < num_columns; i++)
  52.             {
  53.                 columns[i].Left = step * i;
  54.                 columns[i].Width = Width / num_columns;
  55.             }
  56.         }
  57.  
  58.         protected override void OnPaint(PaintEventArgs e)
  59.         {
  60.             base.OnPaint(e);
  61.             e.Graphics.DrawRectangle(Pens.Black, new Rectangle(e.ClipRectangle.X,e.ClipRectangle.Y,e.ClipRectangle.Width-1,e.ClipRectangle.Height-1));
  62.         }
  63.  
  64.  
  65.         protected override void OnResize(EventArgs e)
  66.         {
  67.             base.OnResize(e);
  68.  
  69.             try
  70.             {
  71.                 positionColumns(columns.Count);
  72.             }
  73.             catch { }
  74.  
  75.             Invalidate();
  76.         }



In alternativa puoi usare il resto della larghezza per le colonne

columns.Width = Width % num_columns;
ti ho solo mostrato ciò che dovevi sapere ora tocca a te procedere

Ultima modifica effettuata da Thejuster il 14/03/2017 alle 15:03


PM Quote
Avatar
Sevenjeak (Normal User)
Pro


Messaggi: 84
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 20:04
Martedì, 14/03/2017
Ho provato il tuo codice, le colonne me le inserisce tutte, tranne un piccolo spazio vuoto che mi lascia dopo l'ultima colonna.

Però non era ciò che volevo, non so se si è capito dal mio messaggio precedente, ma l'array percentSize si riferiva alla dimensione in percentuale dei panelli inseriti all'interno del componente, cosa centra che il componente è già  posizionato? l'avevo inserita per far si che l'utente decidesse che se ad esempio voleva impostale la colonna ( i panelle all'interno del controllo, no il controllo stesso ) centrare più grosso ( ad esempio il primo panello e il terso panello occupano il 10% della dimensione totale del contenitore, mentre il secondo, quello posizionato al centro tra i due, occupi il restante.

Hai presente, che nel controllo TableLayoutPanel c'è la possibilità di decidere la dimensione in percentuale di ogni singola colonna? ecco, io con percentSize gli vorrei dire quello, la dimensione di ogni singola colonna

Non ho capito la necessità  del metodo OnPaint() obbligatorio da dichiarare, in questo caso il metodo non viene direttamente ereditato dalla classe padre, la classe controlContainer?

Avevo pensato anche io a inserire il metodo OnResize(), ma pensando al fatto di provare il codice senza ridimensionare il form, visto che l'evento onResize() si verifica al ridimensionamento degli oggetti, ho pensato di inserirlo dopo aver provato tutto il codice, ma a quanto pare mi sbagliavo.

Ultima modifica effettuata da Sevenjeak il 15/03/2017 alle 9:38


Programmando si impara..
PM Quote