Difference between revisions of "CSharp:WindowsForm Tips"
From Aino Wiki
(→Popolamento Bindig) |
(No difference)
|
Latest revision as of 16:19, 20 March 2024
Contents
Interfaccia
Form
Ricerca di un controllo
Dopo aver aggiunto dinamicamente dei controlli può esser necessario trovarli per cambiarne il contenuto ad es.:TextBox tbx = this.Controls.Find("textBox1", true).FirstOrDefault() as TextBox; tbx.Text = "found!";
Aggiornamento Label di un Form
Ecco come aggiornate una label in un loop al fine di tener traccia delle iterazioni. Usando il metodo Refresh:int portNr = Convert.ToInt32(this.TxtPortServer.Text); int localPortNr = Convert.ToInt32(this.TxtLocalPort.Text); string ipServerAddress = this.TxtIPServerAddress.Text; UdpClient udpClient = new UdpClient(localPortNr); do { //udpClient = new UdpClient(localPortNr); byte[] bytes = Encoding.ASCII.GetBytes(this.TxtStringToMessageToSend.Text); udpClient.Send(bytes, (int)bytes.Length, ipServerAddress, portNr); loopCounter++; LabelIteration.Text = loopCounter.ToString(); LabelIteration.Refresh(); //SSNrIteration.r if (ChkLoopInputSentences.Checked) { Thread.Sleep(1 * 1000); } } while (ChkLoopInputSentences.Checked && loopCounter < maxLoop); udpClient.Close();
In realtà occorrerebbe creare un thread separato per fare una cosa pulita, comunque sia ci sono degli hacking (dei trucchi per aggirare l'ostacolo) un di questi è l'uso di Application.DoEvents(), da usare al posto del .Refresh().
Aggiornamento usando Threads
DOC MSDN Microsoft
Poichè la UI è un thread a parte occorre in realtà un meccanismo dedicato per avere gli aggiornamenti, ecco come usando i delegati:
delegate void SetTextCallback(string text); private void MioMetodo() { try { // ... } catch (Exception ex) { SSListnerStatus.Text = "Exception!"; Application.DoEvents(); AppendTxtUDPListnerLog("[MioMetodo()] " + ex.Message); Application.DoEvents(); } } private void AppendTxtUDPListnerLog(string text) { if (this.TxtUDPListnerLog.InvokeRequired) { SetTextCallback d = new SetTextCallback(AppendTxtUDPListnerLog); this.Invoke(d, new object[] { text }); } else { this.TxtUDPListnerLog.Text += text; } }
Cambio stile a controlli dinamicamente
Ecco come cambiare il font ad una label:mainForm.lblName.Font = new Font("Arial", mainForm.lblName.Font.Size);
Cambiando il peso in bold:
LblCompayName.Font = new Font(LblCompayName.Font, FontStyle.Bold);
Evento chiusura Form
Ecco come intercettare l'evento di chiusura di una windows Form applicationFormClosing
(Form closing Exit).// Aggiunta dell'Handler: this.FormClosing += FrmMain_FormClosing; // Ecco un tipico metodo handler di gestione uscita: private void FrmMain_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason == CloseReason.UserClosing) { DialogResult result = MessageBox.Show("Do you really want to exit?", "Dialog Title", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { Environment.Exit(0); } else { e.Cancel = true; } } else { e.Cancel = true; } }
TextBox
Auto scroll down
Ecco come far aggiornare una textBox multiline per andare automaticamente sotto all'ultima aggiunta inserita.
Occorre usare il metodo TextBox.AppendText(string text)
. Se ciò non dovesse funzionare seguire: stackoverflow e l'esempio in stackoverflow
Dopo aver impostato:
Multiline = True ScrollBars = Both
textBox1.SelectionStart = textBox1.Text.Length; textBox1.ScrollToCaret();
Far comparire la clessidra
Per operazioni che richiedono l'attesa dell'utente si può far comparire la clessidra (hourglass) come puntatore. Attenzione a settare il cursore alla sua forma di default dopo la sezione Finally di una Try catch.// Impostazione precedente del puntatore: Cursor previousCursor = Cursor.Current; // Imposta il cursore con la clessidra (hourglass) Cursor.Current = Cursors.WaitCursor; try { // ... operazioni dispendiose di tempo } catch { } finally { // Impostazione del puntatore con la freccia di default Cursor.Current = Cursors.Default; }
Icona applicazione
Per avere sia l'icona associata al Form che quella che appare nella Taskbar occorre valorizzare la proprietà Icon del Form ma anche occorre creare una cartella Resource (sotto la cartella principale del progetto) con dentro un file icona dal nome Icon.ico.
Infine per associare l'icona all'eseguibile occorre andare nelle proprietà del progetto, tab 'application' e associare un file *.ico alla sezione "Resource" 'Icon and manifest'.
Oppure:
InputBox
Come ottenere un semplice dato mediante apposito popup? C# non ha nulla che ci aiuti allora ci posson essere diverse soluzioni che riporto come da Stackoverflow:
MessageBox custom
Originale: stackoverflowAggiungere la seguente classe:public static class Prompt { public static string ShowDialog(string text, string caption) { Form prompt = new Form() { Width = 500, Height = 150, FormBorderStyle = FormBorderStyle.FixedDialog, Text = caption, StartPosition = FormStartPosition.CenterScreen }; Label textLabel = new Label() { Left = 50, Top=20, Text=text }; TextBox textBox = new TextBox() { Left = 50, Top=50, Width=400 }; Button confirmation = new Button() { Text = "Ok", Left=350, Width=100, Top=70, DialogResult = DialogResult.OK }; confirmation.Click += (sender, e) => { prompt.Close(); }; prompt.Controls.Add(textBox); prompt.Controls.Add(confirmation); prompt.Controls.Add(textLabel); prompt.AcceptButton = confirmation; return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : ""; } }
string promptValue = Prompt.ShowDialog("Test", "123");
Usando libreria VisualBasic
Originale: stackoverflow
Referenziare:
try referencing Microsoft.VisualBasic.dllQuindi usare la seguente
Microsoft.VisualBasic.Interaction.InputBox("Question?","Title","Default Text");
using Microsoft.VisualBasic;...
Interaction.InputBox("Question?","Title","Default Text");
ComboBox
Popolamento Bindig
Popola una comboBox usando come data source un dizionario chiave-valore.
private string BindTABDBQuery() { string strError = string.Empty; string strCmbDisplayMember = string.Empty; try { Dictionary<string, string> dctCmbBoxSource = new Dictionary<string, string>(); // Dato il servizio corrente carica le stringhe di connessione al DB #region Popola la combo con le query SQL ovvero i files nella cartella attesa // Carico il contenuto della cartella string[] fileQrySQLPaths = Directory.GetFiles(Model.Configuration.PathDataReadyQuerySQL, "*.sql"); BindingSource bndSrcCmbDBQry_ReadyQueries = new BindingSource(); dctCmbBoxSource = new Dictionary<string, string>(); dctCmbBoxSource.Add("Select a query", string.Empty); foreach (string fileQrySQL in fileQrySQLPaths) { strCmbDisplayMember = Path.GetFileNameWithoutExtension(fileQrySQL); dctCmbBoxSource.Add(strCmbDisplayMember, fileQrySQL); } bndSrcCmbDBQry_ReadyQueries.DataSource = dctCmbBoxSource; CmbDBQry_ReadyQueries.DataSource = bndSrcCmbDBQry_ReadyQueries; CmbDBQry_ReadyQueries.DisplayMember = "Key"; CmbDBQry_ReadyQueries.ValueMember = "Value"; #endregion } catch (Exception ex) { Cursor.Current = Cursors.Default; m_loggerForm.Error("Ex.: '{0}'\r\n\r\n{1}", ex.Message, ex.StackTrace); } return strError; }
Verifica selezione comboBox precedente
private void CmbDBQry_ReadyQueries_SelectedIndexChanged(object sender, EventArgs e) { string strMsgError = string.Empty; string keySQLFile = string.Empty; string fullPathSQLFile = string.Empty; string contentSQLFile = string.Empty; try { Cursor.Current = Cursors.WaitCursor; keySQLFile = ((KeyValuePair<string, string>)CmbDBQry_ReadyQueries.SelectedItem).Key; fullPathSQLFile = ((KeyValuePair<string, string>)CmbDBQry_ReadyQueries.SelectedItem).Value; if (keySQLFile != c_defaultCmbSelQry && !string.IsNullOrWhiteSpace(fullPathSQLFile)) { contentSQLFile = FileHelper.GetTextFileContent(fullPathSQLFile, out strMsgError); if (string.IsNullOrWhiteSpace(strMsgError)) { Cursor.Current = Cursors.Default; MessageBox.Show(string.Format("{0}", strMsgError), string.Format("CmbDBQry_ReadyQueries_SelectedIndexChanged"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } TxtDBQry_EditQryLoaded.Text = contentSQLFile; } } catch (Exception ex) { Cursor.Current = Cursors.Default; m_loggerForm.Error("Ex.: '{0}'\r\n\r\n{1}", ex.Message, ex.StackTrace); MessageBox.Show(string.Format("{0}", ex.Message), string.Format("CmbDBQry_ReadyQueries_SelectedIndexChanged"), MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { Cursor.Current = Cursors.Default; } }
Esempio di popolamento di una ComboBox mediante dati provenienti da un enumerativo e acquisizione dell'enumerativo dalla ComboBox.
Si usa anche ciclare con una FOR EACH sugli elementi della struttura enumerativa.
public enum EnumTxtEncoding { notDefined = 0, ASCII = 1, BigEndianUnicode = 2, Default = 3, Unicode = 4, UTF32 = 5, UTF7 = 6, UTF8 = 7 } public static T ParseEnum<T>(string value) { return (T)Enum.Parse(typeof(T), value, true); } private void FillCmbBxTxtEncoding() { Dictionary<int, string> dctEnumTxtEncoding = new Dictionary<int, string>(); BindingSource bndEnumTxtEncoding = new BindingSource(); foreach (EnumTxtEncoding item in (EnumTxtEncoding[])Enum.GetValues(typeof(EnumTxtEncoding))) { dctEnumTxtEncoding.Add((int)item, item.ToString()); } bndEnumTxtEncoding.DataSource = dctEnumTxtEncoding; CmbBxTxtEncoding.DataSource = bndEnumTxtEncoding; CmbBxTxtEncoding.DisplayMember = "Value"; CmbBxTxtEncoding.ValueMember = "Key"; } //--------------Utilizzo-------------------------------------- string strFileEncoding = null; EnumTxtEncoding fileEncoding = EnumTxtEncoding.notDefined; strFileEncoding = ((KeyValuePair<int, string>)CmbBxTxtEncoding.SelectedItem).Value; fileEncoding = ParseEnum<EnumTxtEncoding>(strFileEncoding);
Pre-Selezione
Il consiglio è di preselezionare medinte l'indice dell'elemento nella lista con cui è popoplata la ComboBox.
Nel seguente esempio la ComboBox è popolata con un dizionario per cui l'indice dell'elemento da selezionare si ottiene trasformando il dizionario dei valori in array ed usando poi la fuinzione di ricerca sull'array!
// Metodo di popolamento della comboBox con in input parametro opzionale il valore da PRE-SELEZIONARE private void Populate_CmbBox_PictureSizeMode(string defaultKeyText = "") { m_dctCmbBoxPictureSizeMode.Add("Normal", PictureBoxSizeMode.Normal); m_dctCmbBoxPictureSizeMode.Add("StretchImage", PictureBoxSizeMode.StretchImage); m_dctCmbBoxPictureSizeMode.Add("AutoSize", PictureBoxSizeMode.AutoSize); m_dctCmbBoxPictureSizeMode.Add("CenterImage", PictureBoxSizeMode.CenterImage); m_dctCmbBoxPictureSizeMode.Add("Zoom", PictureBoxSizeMode.Zoom); BindingSource bndSrcCmbPictureSizeMode = new BindingSource(); bndSrcCmbPictureSizeMode.DataSource = m_dctCmbBoxPictureSizeMode; CmbBox_PictureSizeMode.DataSource = bndSrcCmbPictureSizeMode; CmbBox_PictureSizeMode.DisplayMember = "Key"; CmbBox_PictureSizeMode.ValueMember = "Value"; if (defaultKeyText != string.Empty) { int i = Array.IndexOf(m_dctCmbBoxPictureSizeMode.Keys.ToArray(), defaultKeyText); CmbBox_PictureSizeMode.SelectedIndex = i; } }
TabControl
Come intercettare l'evento cambio di un TAB dell'interfaccia?// Aggiungere manualmente il riferimento gestore dell'evento (l'handler) MioTABControl.Selecting += new TabControlCancelEventHandler(MioTABControl_Selecting); // E poi l'handler che segue private void MioTABControl_Selecting(object sender, TabControlCancelEventArgs e) { TabPage current = (sender as TabControl).SelectedTab; //Si valida la scelta oppure si annulla come segue: e.Cancel = true; }
ListBox
Popolamento con un array di stringhe e gestione della selezione:
private static string[] m_arrStrFilteredItem; //... m_arrStrFilteredItem = GetArraySearchResult(keyToSearch); //Popolamento del ListItem LstB_CredentialFilesFound.DataSource = m_arrStrFilteredItem; private void LstB_CredentialFilesFound_SelectedIndexChanged(object sender, EventArgs e) { string strFileNameSelected = string.Empty; //Selezione del testo del ListItem selezionato! strFileNameSelected = LstB_CredentialFilesFound.GetItemText(LstB_CredentialFilesFound.SelectedItem); Item_BP itemSelected = m_LstDBIndex.Where(x => x.FileName == strFileNameSelected).Single(); BindItem_BP_4Edit(itemSelected); }
GridView
Link interno Soluzioni
PictureBox
Fonti: microsoft.com
PctBx_ImgViewDoc.Image = Image.FromFile("fullPathNomeFile"); //Oppure funziona anche: PctBx_ImgViewDoc.ImageLocation = "fullPathNomeFile";
Per rimuovere l'immagine:
if (PctBx_ImgViewDoc.Image != null) { PctBx_ImgViewDoc.Image.Dispose(); PctBx_ImgViewDoc.Image = null; }
I/O
Intercattare la tastiera
Leggere: learn.microsoft.com KeyPreview.
Occorre abilitare questo comportamento impostando KeyPreview=True;
. Indica se il Form riceverà gli eventi di pressione dei tasti prima che gli stessi risultino conclusi passando al controllo che ha il focus.
E' sufficiente impostare questa proprietà nel costruttore dell'oggetto Form, segue esempio:
namespace MiaApplicazione { public partial class FrmMain : Form { public FrmMain() { this.KeyPreview = true; // <---- !!! InitializeComponent(); } } }
Intercettare un tasto premuto
Si posson intercettare la maggior parte degli eventi di 'tasto premuto' gestendo gli eventi "KeyDown" e "KeyUp" ed occorre tener presente la seguente sequenza completa con cui si susseguono gli eventi:
- KeyDown. Evento generato nonappena l'utente preme un tasto e si ripete continuamente sinché l'utente non lo rilascia;
- KeyPress. Evento generato per i tasti carattere mentre il tasto è premuto e rilasciato. Differisce dagli eventi "KeyDown" e "KeyUp" che son generati ANCHE per i tasti NON carattere.
- KeyUp. Generato DOPO che l'utente ha rilasciato un tasto.
Per gestire l'ultimo degli eventi elencati prima, nell'handler dell'EventLoad del form inserire:
this.KeyUp += new System.Windows.Forms.KeyEventHandler(KeyEvent);
L'handler sarà:
private void KeyEvent(object sender, KeyEventArgs e) //Keyup Event { if (e.KeyCode == Keys.F9) { MessageBox.Show("Function F9"); } if (e.KeyCode == Keys.F6) { MessageBox.Show("Function F6"); } else MessageBox.Show("No Function"); }
Tasti fereccia
Ambiente
Rete
Ottenere l'IP ed il nome della macchina locale (Da stackoverflow):
String strHostName = string.Empty; public static string GetLocalIPAddress() { var host = Dns.GetHostEntry(Dns.GetHostName()); foreach (var ip in host.AddressList) { if (ip.AddressFamily = AddressFamily.InterNetwork) { return ip.ToString(); } } throw new Exception("Local IP Address Not Found!"); }
Mappa e Links
C# | Windows Form | Applicazioni Grafiche