Ho due domande.Metodo di sovrascrittura C# in Runtime
1) Ho trovato un piccolo gioiello di codice per how to make a control scroll smoothly.
Grande. Ma sovrascrive il metodo WndProc, quindi per usarlo, dovevo strappare il FlowLayoutPanel che avevo lasciato sul modulo in fase di progettazione, sottoclassi FlowLayoutPanel, e infine creare un'istanza della mia nuova classe e creare manualmente tutte le proprietà e modificare tutti i riferimenti al controllo per essere questo.Controls ["ControlName"]. (O immagino di poter creare una variabile a livello di classe che è essenzialmente ciò che originariamente era il controllo, anche se come ti permettono di usare intellisense su di esso quando non è dichiarato da nessuna parte?)
Quindi ora mi chiedo se c'era in effetti un modo runtime per farlo.
Posso fare qualcosa di semplice come questo, in cui MainPanel è il nome del controllo:
MainPanel = (SmoothScrollingFlowLayoutPanel)MainPanel
Non può essere così facile, vero? Anche così, è fastidioso perché devo ancora avere la sottoclasse (che potrebbe essere una buona decisione di progettazione, ma mi piacerebbe la libertà di renderla unica). Quindi sarebbe possibile mettere il codice nel genitore del qualcosa FlowLayoutPanel come questo:
private Delegate void WndProcHandler(ref Message m);
private WndProcHandler w;
public void SomeCode() {
w = MainPanel.WndProc; // get reference to existing wndproc method
MainPanel.WndProc = WndProcSmoothScroll; //replace with new method
}
private void WndProcSmoothScroll(ref Message m) { // make smooth scrolling work
if (
(m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL)
&& (((int)m.WParam & 0xFFFF) == 5)
) {
m.WParam = (IntPtr)(((int)m.WParam & ~0xFFFF) | 4);
}
if (w != null) { w(); }
base.WndProc(ref m);
}
Mi rendo conto che questo è probabilmente abbastanza ingenuo. Sto trattando il metodo WndProc come se fosse un evento, e non lo è.
2) Così poi la mia seconda domanda è, se WndProc era un evento invece di un metodo, come vorrei fare la stessa cosa punto vendita una copia della lista originale dei gestori per un evento, installare il mio proprio evento gestore di eseguire prima, quindi chiamare tutti i gestori di eventi originali?
BITS SAPORITI
Nel caso in cui qualcuno è interessato ho notato un'ottimizzazione possibile nel codice scorrimento continuo:
//m.WParam = (IntPtr)(((int)m.WParam & ~0xFFFF) | 4);
m.WParam = (IntPtr)((int)m.WParam^1);
Dal momento che vogliamo trasformare gli ultimi 16 bit 5-4, abbiamo può semplicemente capovolgere l'ultimo bit (XOR) piuttosto che AND poi OR.
Grazie Zach, ma ho già compiuto facendo scorrere le finestre senza problemi. Ho solo odiato il modo in cui dovevo strappare il controllo al designer e fare tutto dinamicamente. – ErikE
@Emtucifor: Nessun problema, volevo solo farti sapere che non dovevi ereditare da 'FlowLayoutPanel' per sovrascrivere il suo' WndProc'. –
Oh, ora capisco. Grazie. Confesso che non ho letto con la stessa attenzione che avrei dovuto. Questo è utile! In effetti, hai ragione al 100%, è la risposta che stavo cercando. (sa di fronte) – ErikE