PDA

View Full Version : [C# - VS2005]Menu riusabile ed eventi buttons


RaouL_BennetH
14-01-2008, 10:41
Ciao a tutti :)

Ho fatto una piccola classe che mi serve per avere sempre a portata di mano un menu da riutilizzare nei miei programmini. Quello che non riesco a capire, è come associare ai button presenti nel menu, i vari eventi come ad esempio il "click".

Il codice della classe è questo:


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

namespace ReusableCode
{
partial class ReusableMenu
{


private ToolStrip generalMenu;
private ToolStripMenuItem prepareNew;
private ToolStripMenuItem prepareSave;
private ToolStripMenuItem prepareUpdate;
private ToolStripMenuItem prepareDelete;
private ToolStripMenuItem prepareCancel;
private ToolStripMenuItem preparePrint;
private ToolStripMenuItem prepareExit;
private ToolStripSeparator[] sep;


public ToolStrip MyMenu()
{
this.generalMenu = new ToolStrip();
this.prepareNew = new ToolStripMenuItem();
this.prepareSave = new ToolStripMenuItem();
this.prepareUpdate = new ToolStripMenuItem();
this.prepareDelete = new ToolStripMenuItem();
this.prepareCancel = new ToolStripMenuItem();
this.preparePrint = new ToolStripMenuItem();
this.prepareExit = new ToolStripMenuItem();
this.sep = new ToolStripSeparator[6];
this.sep[0] = new ToolStripSeparator();
this.sep[1] = new ToolStripSeparator();
this.sep[2] = new ToolStripSeparator();
this.sep[3] = new ToolStripSeparator();
this.sep[4] = new ToolStripSeparator();
this.sep[5] = new ToolStripSeparator();

this.generalMenu.SuspendLayout();
this.generalMenu.Dock = DockStyle.Top;
this.generalMenu.GripStyle = ToolStripGripStyle.Visible;
this.generalMenu.Items.AddRange(new ToolStripItem[] { this.prepareNew,
this.sep[0],
this.prepareSave,
this.sep[1],
this.prepareUpdate,
this.sep[2],
this.prepareDelete,
this.sep[3],
this.prepareCancel,
this.sep[4],
this.preparePrint,
this.sep[5],
this.prepareExit });

this.generalMenu.Location = new Point(3, 0);
this.generalMenu.Name = "mainMenu";
this.generalMenu.Size = new Size(1000, 25);
this.generalMenu.TabIndex = 0;


this.prepareNew.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.prepareNew.Name = "AddNew";
this.prepareNew.Size = new Size(66, 22);
this.prepareNew.Text = "&Nuovo";
this.prepareNew.Font = new Font("Verdana", 9F);
this.prepareNew.ForeColor = Color.SteelBlue;

this.prepareSave.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.prepareSave.Name = "SaveIt";
this.prepareSave.Size = new Size(66, 22);
this.prepareSave.Text = "&Salva";
this.prepareSave.Font = new Font("Verdana", 9F);
this.prepareSave.ForeColor = Color.SteelBlue;

this.prepareUpdate.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.prepareUpdate.Name = "Update";
this.prepareUpdate.Size = new Size(66, 22);
this.prepareUpdate.Text = "&Modifica";
this.prepareUpdate.Font = new Font("Verdana", 9F);
this.prepareUpdate.ForeColor = Color.SteelBlue;

this.prepareDelete.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.prepareDelete.Name = "Delete";
this.prepareDelete.Size = new Size(66, 22);
this.prepareDelete.Text = "&Elimina";
this.prepareDelete.Font = new Font("Verdana", 9F);
this.prepareDelete.ForeColor = Color.SteelBlue;

this.prepareCancel.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.prepareCancel.Name = "Cancel";
this.prepareCancel.Size = new Size(66, 22);
this.prepareCancel.Text = "&Annulla";
this.prepareCancel.Font = new Font("Verdana", 9F);
this.prepareCancel.ForeColor = Color.SteelBlue;

this.preparePrint.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.preparePrint.Name = "Print";
this.preparePrint.Size = new Size(66, 22);
this.preparePrint.Text = "Stam&pa";
this.preparePrint.Font = new Font("Verdana", 9F);
this.preparePrint.ForeColor = Color.SteelBlue;

this.prepareExit.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.prepareExit.Name = "Exit";
this.prepareExit.Size = new Size(66, 22);
this.prepareExit.Text = "Esci";
this.prepareExit.Font = new Font("Verdana", 9F);
this.prepareExit.ForeColor = Color.SteelBlue;
this.prepareExit.Click += new EventHandler(this.prepareExit_Click);

this.generalMenu.ResumeLayout(false);
this.generalMenu.PerformLayout();

return generalMenu;
}

void prepareExit_Click(object sender, EventArgs e)
{
//come associo ad esempio la chiusura del form dove andrò a mettere il mio menu?


}



}
}


Supponendo di avere un form chiamato FormTest, il codice che io vado a scrivere è:


ReusableMenu rm = new ReusableMenu();
menuContainer.Controls.Add(rm.MyMenu());


Come associo ai vari bottoni (come nell'esempio del codice della classe) come devono comportarsi all'interno del form nel quale il menu verrà piazzato?

Grazie mille :)

RaouL.

isAlreadyInUse
14-01-2008, 13:43
bottone.Click += new EventHandler(this.prepareExit_Click);
Intendi questo?

RaouL_BennetH
14-01-2008, 15:12
bottone.Click += new EventHandler(this.prepareExit_Click);
Intendi questo?

Si :)

Il fatto è che non capisco come associargli l'uscita dal o dai form.

Cioè, cosa ci dovrebbe andare nel metodo prepareExit_Click ?

Al momento, riesco a chiuderlo perchè conosco il nome del form e faccio:


foreach(Form f in Application.OpenForms)
{
if(f is FormProva)
{
f.Close();
break;
}
}


Ovviamente questo metodo non mi serve a nulla perchè se piazzo a runtime il menu su decine di forms...... ti lascio immaginare ..

Idee?

Grazie.

Raoul.

isAlreadyInUse
14-01-2008, 15:51
Secondo me dopo aver aggiunto il menu alla form devi settare nella stessa gli eventi che vuoi impostare a i bottoni in modo da avere eventi diverdi a ogni form

RaouL_BennetH
14-01-2008, 16:02
Secondo me dopo aver aggiunto il menu alla form devi settare nella stessa gli eventi che vuoi impostare a i bottoni in modo da avere eventi diverdi a ogni form

mmm...

ma dal form io non ho modo di accedere ai bottoni.

Per uno in particolare però l'evento sarebbe uguale per tutti i form, riferendomi proprio al bottone "Exit", che non dovrebbe far altro che chiudermi il form corrente.

ReaToMe
14-01-2008, 16:15
Passa l'istanza della WinForm al costruttore della classe e memorizzala in una variabile membro privata.

RaouL_BennetH
14-01-2008, 16:18
Passa l'istanza della WinForm al costruttore della classe e memorizzala in una variabile membro privata.

perdonami, ma potresti farmi un esempio?

Non ci ho capito molto :(

fek
14-01-2008, 16:19
Ma la domanda sorge spontanea? Perche' stai cercando di scrivere una classe riusabile? Non puoi semplicemente scrivere una classe che risolve il tuo problema nel programma che stai scrivendo in questo momento?

RaouL_BennetH
14-01-2008, 16:27
Ma la domanda sorge spontanea? Perche' stai cercando di scrivere una classe riusabile? Non puoi semplicemente scrivere una classe che risolve il tuo problema nel programma che stai scrivendo in questo momento?

O_o ma ciao!! :D :ave:

ehm.. perdonate l'ot...

Di solito faccio così. Il fatto è che ultimamente sto lavorando molto su accoppiata interfaccia grafica + database per programmi diversi, e mi ritrovo a dover disegnare praticamente sempre gli stessi menu e gli stessi forms, perciò stavo cercando di risolvere il problema alla radice. Ovvero, avere un paio di forms "generici" ed un menu standard per le operazioni classiche che si fanno su un database.

Ciao :)

ReaToMe
14-01-2008, 16:42
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ReusableCode {
public class ReusableMenu : ToolStrip {

private System.Windows.Forms.Form _container;

public ReusableMenu(System.Windows.Forms.Form container) {

this._container = container;

this.SuspendLayout();

this.Dock = DockStyle.Top;
this.GripStyle = ToolStripGripStyle.Visible;
this.Location = new Point(3, 0);
this.Name = "mainMenu";
this.Size = new Size(1000, 25);
this.TabIndex = 0;

this.AddNewButton("NewMenuItem", "&Nuovo", null);
this.AddNewSeparator();
this.AddNewButton("SaveMenuItem", "&Salva", null);
this.AddNewSeparator();
this.AddNewButton("UpdateMenuItem", "&Modifica", null);
this.AddNewSeparator();
this.AddNewButton("DeleteMenuItem", "&Elimina", null);
this.AddNewSeparator();
this.AddNewButton("CancelMenuItem", "&Annulla", null);
this.AddNewSeparator();
this.AddNewButton("PrintMenuItem", "Stam&pa", null);
this.AddNewSeparator();
this.AddNewButton("ExitMenuItem", "Esci", ExitMenuItem_Click);

this.ResumeLayout(false);
this.PerformLayout();

}

void AddNewButton(string name, string text, EventHandler eventHandler) {
ToolStripMenuItem newButton = new ToolStripMenuItem();

newButton.DisplayStyle = ToolStripItemDisplayStyle.Text;
newButton.Name = text;
newButton.Size = new Size(66, 22);
newButton.Text = name;
newButton.Font = new Font("Verdana", 9F);
newButton.ForeColor = Color.SteelBlue;

if(eventHandler != null)
newButton.Click += new EventHandler(eventHandler);

this.Items.Add(newButton);

newButton = null;

}

void AddNewSeparator() {

ToolStripSeparator newSeparator = new ToolStripSeparator();

this.Items.Add(newSeparator);

newSeparator = null;

}

void ExitMenuItem_Click(object sender, EventArgs e) {

this.MyContainer.Close();

}

System.Windows.Forms.Form MyContainer {
get {
return this._container;
}
}

}
}

ReaToMe
14-01-2008, 16:45
Nella form scriverai

menuContainer.Controls.Add(new ReusableMenu(this));

fek
14-01-2008, 16:59
O_o ma ciao!! :D :ave:

ehm.. perdonate l'ot...

Di solito faccio così. Il fatto è che ultimamente sto lavorando molto su accoppiata interfaccia grafica + database per programmi diversi, e mi ritrovo a dover disegnare praticamente sempre gli stessi menu e gli stessi forms, perciò stavo cercando di risolvere il problema alla radice. Ovvero, avere un paio di forms "generici" ed un menu standard per le operazioni classiche che si fanno su un database.

Ciao :)


Allora prova ad approcciare il discorso cosi' invece: una volta che hai scritto quella classe due volte in maniera simile, prova a tirare fuori una classe comune ai due casi e poi quella diventa una classe di partenza che "proverai" ad usare in futuro.

Non partire cercando di scrivere la classe riusabile subito, perche' nove volte su dieci ti ritrovi con una classe troppo generica che ti fa perdere piu' tempo di quanto te ne fa risparmiare.

RaouL_BennetH
15-01-2008, 12:04
Allora prova ad approcciare il discorso cosi' invece: una volta che hai scritto quella classe due volte in maniera simile, prova a tirare fuori una classe comune ai due casi e poi quella diventa una classe di partenza che "proverai" ad usare in futuro.

Non partire cercando di scrivere la classe riusabile subito, perche' nove volte su dieci ti ritrovi con una classe troppo generica che ti fa perdere piu' tempo di quanto te ne fa risparmiare.

Mi sto confondendo allora :(

Cioè, nel mio percorso di studio verso i linguaggi orientati agli oggetti (in particolare quelli che sto studiando io sono Java e C#... e quest'ultimo mi piace un pelino di più .. ) una delle cose che cercano di passare come "dogma" è quello del riutilizzo del codice. Come devo considerare quindi questa cosa?

Grazie :)

RaouL.

RaouL_BennetH
15-01-2008, 12:18
@ReaToMe:

Grazie mille :) Il tuo codice mi è stato di grandissimo aiuto !

ReaToMe
15-01-2008, 12:20
Di nulla, alla prossima!!!

isAlreadyInUse
15-01-2008, 12:27
Che ne dici di questa soluzione?

ReaToMe
15-01-2008, 12:38
Che spero sia uno scherzo...
Contiene due form che non fanno nulla.

isAlreadyInUse
15-01-2008, 12:41
Il form CRUDForm definisce la struttura, l'altro la eredita, nell'esempio sono dei bottoni ma nel caso di raoul puo essere un menu nel quale va solo a ridefinire gli eventi

fek
15-01-2008, 12:43
Mi sto confondendo allora :(

Cioè, nel mio percorso di studio verso i linguaggi orientati agli oggetti (in particolare quelli che sto studiando io sono Java e C#... e quest'ultimo mi piace un pelino di più .. ) una delle cose che cercano di passare come "dogma" è quello del riutilizzo del codice. Come devo considerare quindi questa cosa?


Considerala una fesseria :D
Il CoCoMo model (http://en.wikipedia.org/wiki/COCOMO) (nome stupidissimo per altro) per la stima del costo del software ha calcolato che scrivere codice per essere riusabile costa mediamente il 30% in piu' (in termini di tempo e denaro) e solo il 10% delle volte e' effettivamente riutilizzato. In pratica, scrivendo codice riutilizzabile paghi in termini di tempo e complessita' della soluzione senza ricevere nulla in cambio nella maggior parte dei casi.
Inoltre, riutilizzare codice non e' facile e impone una maggiore complessita' anche nel codice cliente.

E' molto meglio cercare di "estrarre" codice da riutilizzare da una soluzione gia' funzionante ed estrarre solo il codice gia' diventato semplice, stabile e generico dopo il refactoring.

ReaToMe
15-01-2008, 12:57
...dove codice riusabile è riferito per lo più a sotto-sistemi.
Creare classi riusabili come quella del topic, non è una perdita di tempo.
In fondo si tratta essenzialmente di un control custom.

fek
15-01-2008, 13:05
...dove codice riusabile è riferito per lo più a sotto-sistemi.
Creare classi riusabili come quella del topic, non è una perdita di tempo.
In fondo si tratta essenzialmente di un control custom.

Invece e' quasi sempre una perdita di tempo :)
Perche' per rendere qualcosa riutilizzabile devi renderlo piu' generico, e rendere qualcosa piu' generico vuol dire sempre introdurre piu' complessita', e piu' complessita' vuol dire costi maggiori di manutenzione.

Ricorda che ogni singola riga di codice che scrivi e' una riga di codice che in futuro dovrai mantenere. Magari se scrivi qualche migliaia di righe di codice non cambia molto, ma se ne scrivi centinaia di migliaia in una code base di milioni di righe di codice, vedi che i costi di manutenzione diventano enormi.

E inizi a togliere codice ovunque puoi.

RaouL_BennetH
15-01-2008, 13:07
Inoltre, uno degli scopi che stavo cercando di prefiggermi era anche perdere meno tempo in un altro senso:

Quello che trovo più noioso ogni volta è dover disegnare textbox e label sui form per l'interfacciamento con il database. Stavo cercando di realizzare qualcosa che mi permettesse di recuperare i nomi delle colonne dalla tabella del database e fare in modo di disegnare automaticamente tante caselle di testo per quante colonne ci sono nella tabella. Questo, credo, mi farebbe davvero risparmiare una cifra di tempo.

Tutto ciò in linea teorica... :) perchè in pratica ancora non sono riuscito a farlo.

RaouL_BennetH
15-01-2008, 13:37
@isAlreadyInUse:

Ho appena scaricato il tuo esempio. Lo guardo e ti dico. Nel frattempo grazie mille anche a te :)

Situation....:

Ho capito l'esempio fornitomi da ReaToMe, almeno per quanto riguarda gli eventi relativi al Form in cui viene caricato il menu.

Ora ho un altro problema:

Prendiamo il bottone "Nuovo" e immaginiamo questa situazione:

Sul form c'è un groupbox che contiene diversi oggetti come textbox, combobox etc... che per default all'avvio (load) del form sono disabilitati.

Il tasto "Nuovo" dovrebbe limitarsi a predisporre l'inserimento dei dati, quindi, abilitarmi tutti gli oggetti presenti nel groupbox.

Fino a ieri, io usavo qualcosa del genere:


public void EnableUserInput(Control c)
{
foreach(Control cc in c.Controls)
{
if(cc is GroupBox)
{
GroupBox gp = cc as GroupBox;
gp.Enabled = true;
}
}
}



E questo mi permetteva di abilitare all'istante tutti gli oggetti presenti nel groupbox in questo modo:


//procedura presente nell'evento click del bottone "Nuovo"
private void ButtonNew_Click(object sender, EventArgs e)
{
EnableUserInput(myGroupBox);
}


Adesso, nel codice della classe del menu, ho aggiunto l'evento per il menuitem "Nuovo":


void NewMenuItem_Click(object sender, EventArgs e)
{
//qui dovrei prima identificare se c'è un groupbox in "MyContainer"
//ho provato così:
foreach(Control c in MyContainer.Controls)
{
if(c is GroupBox)
{
GroupBox gp = c as GroupBox;
gp.Enabled = true;
}
}
}


Al click del bottone però, non avviene nulla. Capisco quindi che non riesce ad identificare il groupbox. Nel dubbio, avevo aggiunto anche un MessageBox per cercare di capire se lo identificasse ma non riuscisse ad "interagire", ma il MessageBox resta vuoto.

Grazie ancora per l'aiuto :)

RaouL.

ReaToMe
15-01-2008, 16:12
Invece e' quasi sempre una perdita di tempo :)
Perche' per rendere qualcosa riutilizzabile devi renderlo piu' generico, e rendere qualcosa piu' generico vuol dire sempre introdurre piu' complessita', e piu' complessita' vuol dire costi maggiori di manutenzione.

Ricorda che ogni singola riga di codice che scrivi e' una riga di codice che in futuro dovrai mantenere. Magari se scrivi qualche migliaia di righe di codice non cambia molto, ma se ne scrivi centinaia di migliaia in una code base di milioni di righe di codice, vedi che i costi di manutenzione diventano enormi.

E inizi a togliere codice ovunque puoi.

Quello che dici cozza con anni di letteratura informatica.
Il riuso del codice fatto bene nasce da una buona aggregazione delle responsabilità e dalla creazione di classi coese.
Che fino a prova contraria sono tra le basi della buona OOP.

Se per la gestione degli eventi usi il Command Pattern adeguatamente, ti ritrovi ad avere un menu di base che copre buona parte dei casi standard.

Eventuali comportamenti 'fuori standard' verranno gestiti con un numero eguale di Command.

Niente di complicato, e in un progetto con <n> form che usano un menu così fatto, ti sei tolto di torno (<n>-1)+<righe di codice del menu>.

In una parola? Modularità.

ReaToMe
15-01-2008, 16:19
@isAlreadyInUse:

Ho appena scaricato il tuo esempio. Lo guardo e ti dico. Nel frattempo grazie mille anche a te :)

Situation....:

Ho capito l'esempio fornitomi da ReaToMe, almeno per quanto riguarda gli eventi relativi al Form in cui viene caricato il menu.

Ora ho un altro problema:

Prendiamo il bottone "Nuovo" e immaginiamo questa situazione:

Sul form c'è un groupbox che contiene diversi oggetti come textbox, combobox etc... che per default all'avvio (load) del form sono disabilitati.

Il tasto "Nuovo" dovrebbe limitarsi a predisporre l'inserimento dei dati, quindi, abilitarmi tutti gli oggetti presenti nel groupbox.

Fino a ieri, io usavo qualcosa del genere:


public void EnableUserInput(Control c)
{
foreach(Control cc in c.Controls)
{
if(cc is GroupBox)
{
GroupBox gp = cc as GroupBox;
gp.Enabled = true;
}
}
}



E questo mi permetteva di abilitare all'istante tutti gli oggetti presenti nel groupbox in questo modo:


//procedura presente nell'evento click del bottone "Nuovo"
private void ButtonNew_Click(object sender, EventArgs e)
{
EnableUserInput(myGroupBox);
}


Adesso, nel codice della classe del menu, ho aggiunto l'evento per il menuitem "Nuovo":


void NewMenuItem_Click(object sender, EventArgs e)
{
//qui dovrei prima identificare se c'è un groupbox in "MyContainer"
//ho provato così:
foreach(Control c in MyContainer.Controls)
{
if(c is GroupBox)
{
GroupBox gp = c as GroupBox;
gp.Enabled = true;
}
}
}


Al click del bottone però, non avviene nulla. Capisco quindi che non riesce ad identificare il groupbox. Nel dubbio, avevo aggiunto anche un MessageBox per cercare di capire se lo identificasse ma non riuscisse ad "interagire", ma il MessageBox resta vuoto.

Grazie ancora per l'aiuto :)

RaouL.


Hai aggiunto l'handler?


this.AddNewButton("NewMenuItem", "&Nuovo", NewMenuItem_Click);

fek
15-01-2008, 16:32
Quello che dici cozza con anni di letteratura informatica.
Il riuso del codice fatto bene nasce da una buona aggregazione delle responsabilità e dalla creazione di classi coese.
Che fino a prova contraria sono tra le basi della buona OOP.

Ma quello che dico si sposa con i dati sperimentali e le analisi di costo del software, che e' l'unica cosa che conta.
E' provato che scrivere software riutilizzabile costa il 30% in piu' e quel costo raramente, in pratica, viene amortizzato.


Se per la gestione degli eventi usi il Command Pattern adeguatamente, ti ritrovi ad avere un menu di base che copre buona parte dei casi standard.

E che ogni volta devi adattare al caso particolare dove molto probabilmente una soluzione piu' semplice sarebbe stata perfettamente adeguata allo scopo e costa molto meno da mantenere. Perche' scrivere il codice ha un costo, ma mantenerlo e supportarlo ha un costo maggiore.

La teoria che insegnano all'Universita' va molto bene per qualche progettino di piccole dimensioni, ma quando ti ritrovi a lavorare con code base di milioni di righe di codice, come ho detto, ti accorgi che forse e' molto meglio smettere di overingegnerizzare ed e' molto meglio iniziare a scrivere codice semplice e facile da mantenere. Perche' nove volte su dieci You Ain't Gonna Need It.

C'e' sempre tempo per rifattorizzare e estrarre dalla code base codice piu' generico che puo' essere riutilizzato.


In una parola? Modularità.

In una parola? Keep It Simple, Sweety (Sono quattro parole :))

ReaToMe
15-01-2008, 17:00
Ma quello che dico si sposa con i dati sperimentali e le analisi di costo del software, che e' l'unica cosa che conta.
E' provato che scrivere software riutilizzabile costa il 30% in piu' e quel costo raramente, in pratica, viene amortizzato.

Potrei tirare fuori altrettanti dati sperimentali che sostengono l'esatto contrario.

E che ogni volta devi adattare al caso particolare dove molto probabilmente una soluzione piu' semplice sarebbe stata perfettamente adeguata allo scopo e costa molto meno da mantenere. Perche' scrivere il codice ha un costo, ma mantenerlo e supportarlo ha un costo maggiore.

Con conseguente copia/incolla del codice, rindondanza e 2x di linee di codice da mantenere.
Per questi casi c'è una stupidata dell'OOP chiamata ereditarietà...

La teoria che insegnano all'Universita' va molto bene per qualche progettino di piccole dimensioni, ma quando ti ritrovi a lavorare con code base di milioni di righe di codice, come ho detto, ti accorgi che forse e' molto meglio smettere di overingegnerizzare ed e' molto meglio iniziare a scrivere codice semplice e facile da mantenere. Perche' nove volte su dieci You Ain't Gonna Need It.

Quindi l'ultimo framework che ho fatto per la mia azienda lo devo buttare al cesso. Mannaggia.
C'è un limite ben delineato tra ingegnerizzazione e overingegnerizzare.
Sicuramente overingegnerizzare non è sinonimo di riusabilità.

C'e' sempre tempo per rifattorizzare e estrarre dalla code base codice piu' generico che puo' essere riutilizzato.

Da quello che dici mi dai l'idea di avere un approccio un po' procedurale all'OOP.

In una parola? Keep It Simple, Sweety (Sono quattro parole :))


Troppe. 4 volte la mia.

Il codice riusabile (se scritto bene) tra i tanti pregi ne ha tre enormi:
1) Riduce il numero di Code-Line.:eek:
2) Localizza le responsabilità e rende le classi coese.:eek:
3) Evita la rindondanza.:eek:

Se poi questo per te può essere causa di overhead nella manutenzione...

PS
Non mi ricordo manco come è fatta un'università:rolleyes:

fek
15-01-2008, 17:39
Potrei tirare fuori altrettanti dati sperimentali che sostengono l'esatto contrario.

Fallo.


Con conseguente copia/incolla del codice, rindondanza e 2x di linee di codice da mantenere.
Per questi casi c'è una stupidata dell'OOP chiamata ereditarietà...

A parte "Prefer Composition Over Inheritance", l'ereditarieta' e' spesso e volentieri una cosa negativa e va usata con parsimonia. Meglio comporre oggetti.
Ma chi ha parlato di ridondanza e duplicazione? :)
La duplicazione va eliminata al volo, appena si presenta, "Don't Repeate Yourself".


Quindi l'ultimo framework che ho fatto per la mia azienda lo devo buttare al cesso. Mannaggia.
C'è un limite ben delineato tra ingegnerizzazione e overingegnerizzare.
Sicuramente overingegnerizzare non è sinonimo di riusabilità.

Hmmm... Non esistono framework, esistono soluzioni, l'ultimo che qui voleva scrivere un framework per fare il build asset... e' ancora li' la notte che fissa bug.


Da quello che dici mi dai l'idea di avere un approccio un po' procedurale all'OOP.

Io, procedurale? :)


Troppe. 4 volte la mia.

Ma segnano la differenza fra un buon programmatore e uno che scrive codice.


Il codice riusabile (se scritto bene) tra i tanti pregi ne ha tre enormi:
1) Riduce il numero di Code-Line.:eek:
2) Localizza le responsabilità e rende le classi coese.:eek:
3) Evita la rindondanza.:eek:

Se poi questo per te può essere causa di overhead nella manutenzione...


Si', lo e', perche' e' vero l'esatto contrario. Scrivere constantemente per la riusabilita' (oltre come ho detto a costare il 30% in piu' e non portare benefici), tende ad aumentare le righe di codice da mantenere, perche' significa produrre soluzioni piu' generiche e complesse per essere riutilizzabili, dove una soluzione meno complessa poteva essere perfettamente adeguata. Non evita la ridondanza, anzi, tende a promuoverla perche' tende ad aumentare la complessita'. Non localizza le responsabilita', ma tende ad aumentare la genericita' degli oggetti rendendoli quindi meno coesi e piu' complessi.
Hai mai avuto a che fare con code base di qualche milione di righe di codice?

La mia lotta contro la sovraingegnerizzazione del codice non avra' mai fine...
Keep It Simple, Silly :)

ReaToMe
15-01-2008, 17:54
Mai letti così tanti ossimori in una volta.

fek
15-01-2008, 17:58
Mai letti così tanti ossimori in una volta.

Mostrameli. E spiega il perche' sarebbero ossimori. Ti assicuro che e' molto piu' probabile che ti stia sfuggendo qualche passaggio del mio discorso.

Anzi, apri un bel topic sulla riusabilita' del codice e ti spiego li' per filo e per segno perche' scrivere per riutilzzare il codice (e non il riutilizzo di codice di per se') non e' una buona idea.

wingman87
15-01-2008, 18:18
@Raoul: mi sembra che per fare quello che vorresti fare (piazzare i controlli in base alle colonne che hai nelle tabelle del db) c'è un modo semplice di farlo con l'IDE, io almeno l'avevo fatto con VB (sempre il .NET) quindi immagino si possa fare anche in C#, ora però non saprei dirti di più ma sicuramente su internet trovi qualcosa al riguardo...

ReaToMe
15-01-2008, 18:19
Mostrameli. E spiega il perche' sarebbero ossimori. Ti assicuro che e' molto piu' probabile che ti stia sfuggendo qualche passaggio del mio discorso.

Sempre IMHO naturalmente.
Ho espresso la mia opinione, nuda e cruda.
Per quanto mi riguarda quel che dici fa' a pugni con la mia esperienza lavorativa.
Avere una archittettura semplice e allo stesso tempo riusabile per me non è assolutamente difficile.
Semplicemente è la mia realtà quotidiana.
E non ho bisogno di fare un lavoro di affinamento successivo (che ha un costo) per ottenere classi, sottosistemi o sistemi riusabili.
Ho avuto a che fare con progetti di svariate dimensioni.
Ed ho sempre applicato queste regole.
Non credo che l'ereditarietà sia superiore alla composizione o viceversa, vanno a braccetto.
La complessità di certe soluzioni riusabili nasce non tanto dalle linee di codice, ma tanto dal maggior livello di collaborazione che si instaura tra gli oggetti, che viene ripagata da una maggiore area di copertura del dominio.
Rindondanza e complessità non sono collegabili.
Sviluppare senza un occhio alla riusabilità porta ad avere parti di codice ripetute. E questa è rindondanza. Che comporta per una singola modifica, n interventi pressochè identici.
Rendere una classe riusabile non significa renderla meno coesa.
Ammesso che uno non ci infili tutto quello che gli passa per la testa.
Ti sembra che la classe postata prima sia poco coesa? Eppure è riusabile.
C'è chi la complessità la spalma nella classe, e chi la gestisce facendo collaborare le classi tra loro. O se preferisci OOP.

fek
15-01-2008, 18:27
Sempre IMHO naturalmente.
Ho espresso la mia opinione, nuda e cruda.
Per quanto mi riguarda quel che dici fa' a pugni con la mia esperienza lavorativa.
Avere una archittettura semplice e allo stesso tempo riusabile per me non è assolutamente difficile.
Semplicemente è la mia realtà quotidiana.
E non ho bisogno di fare un lavoro di affinamento successivo (che ha un costo) per ottenere classi, sottosistemi o sistemi riusabili.

Stai cercando di convincermi che tu hai un problema, e sei in grado di scrivere una soluzione perfetta, riutilizzabile e che non necessita' ne' affinamenti ne' refactoring al primo colpo?
Se e' davvero cosi', ti prego, spiegami come fai, scriviamo un libro e ci facciamo i milioni.
Perche' non c'e' riuscito ancora nessuno al mondo :D

Avere un'architettura semplice e riusabile e' impossibile, sono due obiettivi che remano uno contro l'altro per definizione di "riusabilita'", ovvero qualcosa che puo' essere riusato in progetti diversi con finalita' diverse, ovvero generico. La genericita' ha sempre un costo in termini di complessita'.

Non credo che l'ereditarietà sia superiore alla composizione o viceversa, vanno a braccetto.

Credi male, perche' una classe che eredita da un'altra ha un valore di coupling maggiore rispetto alla stessa classe in composizione con l'altra. E' dimostrato che valori di coupling piu' alti, statisticamente, generano piu' difetti. Dunque, dove la composizione risolve il problema, e' sempre preferibile all'ereditarieta'.

Sviluppare senza un occhio alla riusabilità porta ad avere parti di codice ripetute. E questa è rindondanza. Che comporta per una singola modifica, n interventi pressochè identici.

Falso. Scrivo centinaia di migliaia di linee di codice l'anno, non scrivo NULLA per essere riusato (perche' mi costa il 30% in piu', te lo ricordo, e ancora non mi hai portato controesempi), eppure e' difficile trovare mio codice duplicato. Diciamo impossibile: rifattorizzo in continuazione.

Rendere una classe riusabile non significa renderla meno coesa.
Ammesso che uno non ci infili tutto quello che gli passa per la testa.
Ti sembra che la classe postata prima sia poco coesa? Eppure è riusabile.
C'è chi la complessità la spalma nella classe, e chi la gestisce facendo collaborare le classi tra loro. O se preferisci OOP.

Tutto e' per definizione riusabile, il problema non e' questo. Il problema e' quanto costa riusarlo e, come ho detto, costa piu' che scrivere il codice piu' semplice possibile che risolve il problema. Si chiama pragmatismo. O saper programmare (in OOP) :)

PS. Citi spesso l'OOP, ma ti assicuro che "Prefer Composition Over Inheritance" e' uno dei concetti base della programmazione orientata ad oggetti (cfr Design Patterns, Gang Of Four).

Apri un topic, continuiamo li'.

ReaToMe
15-01-2008, 18:31
Stai cercando di convincermi che tu hai un problema, e sei in grado di scrivere una soluzione perfetta, riutilizzabile e che non necessita' ne' affinamenti ne' refactoring al primo colpo?
Se e' davvero cosi', ti prego, spiegami come fai, scriviamo un libro e ci facciamo i milioni.
Perche' non c'e' riuscito ancora nessuno al mondo :D

Avere un'architettura semplice e riusabile e' impossibile, sono due obiettivi che remano uno contro l'altro per definizione di "riusabilita'", ovvero qualcosa che puo' essere riusato in progetti diversi con finalita' diverse, ovvero generico. La genericita' ha sempre un costo in termini di complessita'.



Credi male, perche' una classe che eredita da un'altra ha un valore di coupling maggiore rispetto alla stessa classe in composizione con l'altra. E' dimostrato che valori di coupling piu' alti, statisticamente, generano piu' difetti. Dunque, dove la composizione risolve il problema, e' sempre preferibile all'ereditarieta'.



Falso. Scrivo centinaia di migliaia di linee di codice l'anno, non scrivo NULLA per essere riusato (perche' mi costa il 30% in piu', te lo ricordo, e ancora non mi hai portato controesempi), eppure e' difficile trovare mio codice duplicato. Diciamo impossibile: rifattorizzo in continuazione.



Tutto e' per definizione riusabile, il problema non e' questo. Il problema e' quanto costa riusarlo e, come ho detto, costa piu' che scrivere il codice piu' semplice possibile che risolve il problema. Si chiama pragmatismo. O saper programmare (in OOP) :)

PS. Citi spesso l'OOP, ma ti assicuro che "Prefer Composition Over Inheritance" e' uno dei concetti base della programmazione orientata ad oggetti (cfr Design Patterns, Gang Of Four).

Apri un topic, continuiamo li'.

Ti suggerirei di leggere il sottotitolo del libro che hai citato...

fek
15-01-2008, 19:01
Ti suggerirei di leggere il sottotitolo del libro che hai citato...

Conosco quel libro a memoria e non solo quello :)

ReaToMe
15-01-2008, 23:16
Non sei il solo.
Per dovere di cronaca il titolo completo è
"Design Patterns: Elements of Reusable Object-Oriented Software"

fek
15-01-2008, 23:44
Non sei il solo.
Per dovere di cronaca il titolo completo è
"Design Patterns: Elements of Reusable Object-Oriented Software"

E quindi? :)
Se tu avessi compreso il libro, non avresti fatto questa sterile puntualizzazione, perche' sapresti che da nessuna parte la Gang Of Four afferma che il codice deve essere scritto riutilizzabile, ma presenta design che possono essere riutilizzati nella progettazione del software. Sono due concetti estremamente differenti.
Infatti e' profondamente sbagliato pensare di "programmare a design pattern". Tanto e' vero che i design pattern oggi sono usati come uno strumento di documentazione e descrizione del codice, e non piu' come uno strumento di design.

Ora, puoi mostrarmi dove sarebbero i miei ossimori e puoi rispondere alle numerose puntalizzazioni che ho fatto? O pensi ancora che Ereditarieta' e Composizione siano sullo stesso piano? Mi porteresti anche questi numerosi esempi contrari al mio che mostra come scrivere codice riutilizzabile sia piu' costoso? Ti ringrazio.

ReaToMe
16-01-2008, 00:08
Ti basterebbe leggere con attenzione il paragrafo seguente all'enunciazione del principio che hai citato sopra.

Vuoi dire che tu sviluppi senza handler, listener, command, decorator, factory o singleton?
E che non scrivi sempre con una struttura similare?
E che non hai mai consolidato una soluzione per un problema che ti si ripresenta sistematicamente?

Hai le tue convinzioni, ed evidentemente portano frutto al tuo lavoro.
Io ho le mie e come tu con le tue, me le tengo strette.

fek
16-01-2008, 00:16
Ti basterebbe leggere con attenzione il paragrafo seguente all'enunciazione del principio che hai citato sopra.


Ho letto tutto con estrema attenzione.


Vuoi dire che tu sviluppi senza handler, listener, command, decorator, factory o singleton?
E che non scrivi sempre con una struttura similare?
E che non hai mai consolidato una soluzione per un problema che ti si ripresenta sistematicamente?

Ma dove ho mai scritto che sviluppo senza usare design pattern? Li uso, e in abbondanza. Emergono costantemente dal codice che scrivo. Stai facendo tantissima confusione, mi sembra che neppure ti sforzi di capire cio' che sto scrivendo, per partito preso.

Io non sono contro il riutilizzo del codice (l'esatto contrario).
Io non sono contro i Design Pattern (al contrario, un programmatore che non li recita a memoria per me non andrebbe neppure assunto).

Io sono contro la sovraingegnerizzazione e la scrittura del codice con lo scopo di riutilizzarlo, perche' sono pratiche di sviluppo inadeguate e inefficienti.


Hai le tue convinzioni, ed evidentemente portano frutto al tuo lavoro.
Io ho le mie e come tu con le tue, me le tengo strette.

Io non ho alcuna convinzione, mi limito a seguire buone pratiche di sviluppo che sono ampiamente dimostrate produttive, infatti ancora non mi hai portato quei numerosi studi che secondo te dimostrerebbero il contrario...
Io seguivo cio' che tu stai predicando qui dieci anni fa. Poi mi sono trovato di fronte a code base di milioni di righe di codice, lavorando con cinquanta ingegneri, per fortuna non ho avuto la presunzione di tenermi strette le mie convinzioni di allora, ed ho imparato a programmare finalmente e la mia produttivita' e' aumentata.

PS. Si', sviluppo sempre senza Singleton :)

ReaToMe
16-01-2008, 00:34
Considerala una fesseria :D
Il CoCoMo model (http://en.wikipedia.org/wiki/COCOMO) (nome stupidissimo per altro) per la stima del costo del software ha calcolato che scrivere codice per essere riusabile costa mediamente il 30% in piu' (in termini di tempo e denaro) e solo il 10% delle volte e' effettivamente riutilizzato. In pratica, scrivendo codice riutilizzabile paghi in termini di tempo e complessita' della soluzione senza ricevere nulla in cambio nella maggior parte dei casi.

Quale studio?
Quali costi sono stati presi in considerazione?
Con quali processi di sviluppo?

Prova a scrivere su google "oo reusability cost study"

E quindi? :)
Infatti e' profondamente sbagliato pensare di "programmare a design pattern". Tanto e' vero che i design pattern oggi sono usati come uno strumento di documentazione e descrizione del codice, e non piu' come uno strumento di design.

Se mi scrivi questo io penso che tu non gli usi...

fek
16-01-2008, 09:11
Quale studio?
Quali costi sono stati presi in considerazione?
Con quali processi di sviluppo?

Co.Co.Mo Model Software Estimation Model. E' un bel malloppo ma interessante.
Questo e' un ottimo libro sull'argomento:
http://www.amazon.co.uk/Software-Estimation-Demystified-Practices-Microsoft/dp/0735605351/ref=sr_1_1?ie=UTF8&s=gateway&qid=1200475072&sr=8-1

Riporta inoltre diversi casi studio su come scrivere software per essere riusato costi di piu' e, di fatto, mediamente non e' riusato.


Prova a scrivere su google "oo reusability cost study"

Postane uno. Ma che ci siano dei numeri basati su metriche reali :)

Se mi scrivi questo io penso che tu non gli usi...

E pensi molto male, ma non e' la prima volta.
Ma la cosa fastidiosa e' che metti queste frasette per provocare, ma ancora non sei riuscito una volta sola a contestarmi quello che scrivo con qualche argomento :)

ReaToMe
16-01-2008, 10:50
Co.Co.Mo Model Software Estimation Model. E' un bel malloppo ma interessante.
Questo e' un ottimo libro sull'argomento:
http://www.amazon.co.uk/Software-Estimation-Demystified-Practices-Microsoft/dp/0735605351/ref=sr_1_1?ie=UTF8&s=gateway&qid=1200475072&sr=8-1

Riporta inoltre diversi casi studio su come scrivere software per essere riusato costi di piu' e, di fatto, mediamente non e' riusato.

Postane uno. Ma che ci siano dei numeri basati su metriche reali :)


Adoro Steve. Non mancherò di leggerlo.
Code Complete me lo sono passato già tre volte...

Ecco un buon link.

https://www.goldpractices.com/practices/arrc/


E pensi molto male, ma non e' la prima volta.
Ma la cosa fastidiosa e' che metti queste frasette per provocare, ma ancora non sei riuscito una volta sola a contestarmi quello che scrivo con qualche argomento :)

Io non voglio provocare nessuno.
Non posso entrarti nella testa.
Mi limito a leggere quello che scrivi.
Siccome non saresti ne il primo ne l'ultimo che usa i DP solo per documentare, non vedo dove sia lo scandalo.

Argomenti ne ho scritti.
Non li reputi validi? Non so cosa farci.

Non do addosso a nessuno. Mai.
Se ho dato questa impressione, me ne scuso.

Probabilmente siamo partiti con il piede sbagliato.

Quel che penso è che promuovere nei progetti la riusabilità di classi, sottosistemi e sistemi sia cosa buona e giusta.

Questo non significa che io programmi per la riusabilità.
Come tutti programmo per la soluzione al problema.
Ma nel disegnare mi faccio sempre la fatidica domanda:
C'è una parte del sistema che sto progettando/sviluppando che si presta ad un riuso futuro?
Se la valutazione è positiva, progetto in modo che il modulo sia riusabile.

Non credo sia una bad practice, anzi.

fek
16-01-2008, 11:04
Adoro Steve. Non mancherò di leggerlo.
Code Complete me lo sono passato già tre volte...

Ecco un buon link.

https://www.goldpractices.com/practices/arrc/

Interessante, ma dal 2004 le cose sono un po' cambiate, e esempi di aziende che usano il Cobol non sono particolarmente significativi ;)
A parte che in quel documento non c'e' un solo riferimento, ma solo citazioni, non e' mai comunque citato rispetto a quali pratiche i miglioramenti sono ottenuti.

Ti ripeto che io non sono contro il riusare il codice, al contrario, sono contro lo scrivere il codice per riusarlo, perche' costa di piu'.


Io non voglio provocare nessuno.
Non posso entrarti nella testa.
Mi limito a leggere quello che scrivi.
Siccome non saresti ne il primo ne l'ultimo che usa i DP solo per documentare, non vedo dove sia lo scandalo.

Non limitarti a leggere quello che scrivo, cerca anche di comprenderlo.
I DP sono un ottimo strumento di documentazione e di comunicazione del design. E' molto piu' efficiente per me dire al mio collega "Qui sto rifattorizzando verso un Observer" piuttosto che cercare di descrivere il design verso il quale mi sto muovendo.
Ma non impongo mai un Design Patter al codice che sto scrivendo prima di averlo scritto, in pratica io uso i DP, non ne abuso, pensando che cosi' facendo possa riutilizzare il codice.
Anzi, lo facevo dieci anni fa, poi ho smesso.


Argomenti ne ho scritti.
Non li reputi validi? Non so cosa farci.

"Mai letto un post cosi' pieno di ossimori" effettivamente e' un argomento ficcante che mi ha lasciato senza parole :)

Quel che penso è che promuovere nei progetti la riusabilità di classi, sottosistemi e sistemi sia cosa buona e giusta.

E pensi una cosa che e' empiricamente sbagliata, perche' promuovi una pratica che, come ho dimostrato ampiamente, costa circa il 30% in piu' di media e di fatto non apporta benefici perche' il codice solo raramente e' riusato. Ti prego di leggere quel modello di stima del software e gli studi sui quali si basa.

C'è una parte del sistema che sto progettando/sviluppando che si presta ad un riuso futuro?
Se la valutazione è positiva, progetto in modo che il modulo sia riusabile.

Non credo sia una bad practice, anzi.

Si', e' una bad practice ed ha anche un nome: YAGNI (http://c2.com/xp/YouArentGonnaNeedIt.html).

"Always implement things when you actually need them, never when you just foresee that you need them."

71104
16-01-2008, 11:10
mi permetto di introdurmi nel discorso per gettare i miei 2 cents:
Quel che penso è che promuovere nei progetti la riusabilità di classi, sottosistemi e sistemi sia cosa buona e giusta. spero di non ritrovarmi mai ad utilizzare un tuo software: saprei che è pieno di robaccia inutile e che essendo anche molto difficile da mantenere potrebbe essere pieno di errori.

ReaToMe
16-01-2008, 11:18
spero di non ritrovarmi mai ad utilizzare un tuo software: saprei che è pieno di robaccia inutile e che essendo anche molto difficile da mantenere potrebbe essere pieno di errori.

E da cosa nasce questa convinzione?
Sembrerebbe quasi che tu mi stia dando gratuitamente dell'incompetente.
Ma sicuramente avrò capito male.

fek
16-01-2008, 11:48
E da cosa nasce questa convinzione?

La mia convinzione e' simile alla sua e nasce dall'aver lavorato per anno (e lavorarci ancora) con chi cerca di scrivere codice riusabile, me lo riempie di orpelli inutili per renderlo generico, e io ne pago le conseguenze quando devo usarlo.

ReaToMe
16-01-2008, 12:05
La mia convinzione e' simile alla sua e nasce dall'aver lavorato per anno (e lavorarci ancora) con chi cerca di scrivere codice riusabile, me lo riempie di orpelli inutili per renderlo generico, e io ne pago le conseguenze quando devo usarlo.

Non sono di quella pasta. Grazie a Dio.
Credo che un punto di incontro tra i nostri punti di vista possa essere questo.
Mi ci è voluto un po' per ritrovarlo:cool:

http://www.c2.com/cgi/wiki?OaooBalancesYagni

fek
16-01-2008, 12:07
Non sono di quella pasta. Grazie a Dio.
Credo che un punto di incontro tra i nostri punti di vista possa essere questo.
Mi ci è voluto un po' per ritrovarlo:cool:

http://www.c2.com/cgi/wiki?OaooBalancesYagni

We DoTheSimplestThingThatCouldPossiblyWork, that is, we implement each new feature as simply as we can. However, we then reapply the Simplest rule to require that the system be left in as simple a final state as possible. This means that we refactor the code until everything is done OnceAndOnlyOnce (OAOO).

This refactoring, by centralizing any given function to a single class or method, leaves the system well positioned for the next change. Whatever you need to do next, or six months from now, you are almost certain to be able to do it by enhancing or replacing a single isolated object.

Assolutamente si', questo e' il mio modo canonico di operare (milestone rush a parte), e chi ha lavorato a Diamonds sa' che non rispettare questa prassi portava a dolorese conseguenze alle ditine :)
A volte faccio questo refactoring appena finito un task, a volte appena inizio il task successivo che lavora su quel codice. Ma lo faccio sempre.

La cosa curiosa e' che operando in questo modo, alla fine del progetto ci si ritrova con molti sistemi semplici, coesi e facili da riutilizzare in altri progetto. E senza aver scritto una singola riga di codice pensando di riutilizzarla in futuro...

71104
16-01-2008, 12:46
E da cosa nasce questa convinzione? ciascun pezzo di codice, se lo assumiamo completamente privo di parti inutili, può essere riutilizzato solamente in un altro programma che svolge quella funzione in maniera assolutamente identica, situazione che potrebbe essere difficile a presentarsi. non credo ci siano dubbi sul fatto che per riusare bisogna spesso generalizzare (e quindi inevitabilmente aggiungere codice che nella situazione specifica non serve, perifrasi che sta per "sovraingegnerizzare").

Sembrerebbe quasi che tu mi stia dando gratuitamente dell'incompetente.
Ma sicuramente avrò capito male. io non ho detto nulla eh :rolleyes:

fek
16-01-2008, 12:53
ciascun pezzo di codice, se lo assumiamo completamente privo di parti inutili, può essere riutilizzato solamente in un altro programma che svolge quella funzione in maniera assolutamente identica, situazione che potrebbe essere difficile a presentarsi. non credo ci siano dubbi sul fatto che per riusare bisogna spesso generalizzare (e quindi inevitabilmente aggiungere codice che nella situazione specifica non serve, perifrasi che sta per "sovraingegnerizzare").

Questo non e' strettamente vero Alberto. Piu' una classe e' semplice e coesa, piu' e' facile da riutilizzare con minime modifiche in un progetto simile. Ripeto: riutilizzare il codice e' un'ottima pratica.

Il punto e' come arrivare a queste classi semplici e coese e la mia esperienza (e non solo) mi dice che ci si arriva in maniera molto piu' efficiente con un approccio pragmatico alla costruzione del software: scrivi solo quello che ti serve, il piu' semplice possibile, elimina le duplicazioni ovunque siano. Scoprirai che il risultato e' spesso facile da riutilizzare.

RaouL_BennetH
16-01-2008, 13:58
@Raoul: mi sembra che per fare quello che vorresti fare (piazzare i controlli in base alle colonne che hai nelle tabelle del db) c'è un modo semplice di farlo con l'IDE, io almeno l'avevo fatto con VB (sempre il .NET) quindi immagino si possa fare anche in C#, ora però non saprei dirti di più ma sicuramente su internet trovi qualcosa al riguardo...

Si può fare mediante l'ide se usi la versione ms sql, non se usi mysql (come succede a me :( )

@ReaToMe:

Si, l'handler l'ho messo nel codice :)

P.S.: potrei chiedervi di aprire magari un 3d apposito dove continuare per quanto riguarda le vs tesi? :ave:

ReaToMe
16-01-2008, 14:10
Ma ora ti funziona?

RaouL_BennetH
16-01-2008, 14:14
Ma ora ti funziona?

Eh no :(

l'handler l'avevo aggiunto giusto ieri, prendendo esempio dal "prepareExit" e il codice è quello che avevo postato ieri.

ReaToMe
16-01-2008, 14:15
Fai zip e upload e vediamo se si può fare qualcosa...

RaouL_BennetH
16-01-2008, 14:31
eccolo :)

EDIT: non ci sta come dimensione ... :(

ReaToMe
16-01-2008, 14:36
Non lo vedo...

RaouL_BennetH
16-01-2008, 14:40
scusami, eccolo :)

RaouL_BennetH
22-01-2008, 16:50
uppettino :cry: