Événements Initialize, Load et Activate
- Initialize: appelé lors de la création de la Form
- Load: appelé lorsque la Form est chargée en mémoire
- Activate: appelé à chaque fois que la Form devient la fenêtre active
MSDN
Dock et superposition
ElementA docké en Fill et ElementB docké en bottom.
ElementB se retrouve par dessous ElementA et masque le bas d'ElementA.
Solutions:
- Right click sur ElementA and select “Bring to Front”
- Ajouter ce code:
|
private void Form_Load(object sender, EventArgs e)
{
ElementA.BringToFront();
|
Centrer un Label
AutoSize → False
TextAlign → MiddleCenter
Simuler une entrée au clavier
[1]
|
SendKeys.Send("{Tab}");
|
Ajouter un ContextMenuStrip → drag-drop depuis la boite à outils.
Lier le CMS à un élément graphique → via la propriété ContextMenuStrip
Ajouter des éléments au menu → via la propriété Items ou via la petite flèches au dessus du CMS dans le bas de la vue du designer
Lier un événement à la sélection d'un menu → sélectionner l'élément du menu dans la vue du designer et ajouter un handler sur l'évènement Click
La propriété ShotcutKeys permet d'associer un raccourci clavier à un élément du menu.
|
private void tsmi_Click(object sender, EventArgs e)
{
var menu = (ToolStripDropDownItem)sender;
var strip = (ContextMenuStrip)menu.Owner;
var control = (DataGridView)strip.SourceControl;
var control = (DataGridView)ActiveControl;
}
|
Form
Propriétés intéressantes
- ControlBox → Affiche/cache l'icône en haut à gauche ainsi que les boutons réduire, grandir et fermer en haut à droite.
Interdire le redimensionnement
- Propriété FormBorderStyle → FixedSingle
- Propriété MaximizeBox → false
AutoScaleMode
Détermine le comportement du formulaire lors d'un changement de la résolution (dpi) ou de la police (font).
Choisir l'AutoScaleMode du formulaire principal, les sous formulaires peuvent hériter de l'AutoScaleMode de leur parent (Inherit).
La valeur par défaut est font, cela peut causer des problèmes d'affichage. Préférer dpi ou none.
Boutons OK et CANCEL dans une Form
Il faut affecter respectivement les valeurs OK et CANCEL à la propriété DialogResult des boutons.
|
NewForm form = new NewForm();
if (form.ShowDialog(this) == DialogResult.OK) // fenetre modale
{ ... }
form.Dispose();
|
Thread graphique et thread de calcul
Pour que le formulaire soit toujours visible et interactif, il est nécessaire de lancer un second thread qui s'occupera des calcul pendant que le premier thread (thread graphique) s'occupera de l'affichage du formulaire.
Attention, le thread de calcul ne peut pas modifier directement les éléments du formulaire car ils appartiennent à un autre thread. Il faut donc utiliser les callback.
|
Thread thread = new Thread(new ThreadStart(delegate()
{
Thread thread = new Thread(methode);
thread.Start();
|
Callback et thread-safe
Fonction de rappel, permet de passer un pointeur sur fonction en paramètre (délégué).
Dans cet exemple, c’est une méthode qui s’appelle elle-même de manière asynchrone via un délégué.
|
public class MainForm : Form
{
delegate void mainFormCallback(string text);
private void button_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(delegate()
{
SetText("OK");
});
thread.Start();
}
private void SetText (string text)
{
if (this.button.InvokeRequired)
{
mainFormCallback callback = new mainFormCallback(SetText);
this.Invoke(callback, text);
}
else
{
button.Text = text;
}
}
}
|
[2]
DataGridView
Coller des données provenant d'Excel
|
string clipboardText = Clipboard.GetText();
string[] clipboardLines = clipboardText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
var clipboardElements = new List<string>();
foreach (var line in clipboardLines)
{
clipboardElements.AddRange(line.Split('\t'));
}
var orderedSelectedCells = new List<DataGridViewCell>();
foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
{
orderedSelectedCells.Add(cell);
}
orderedSelectedCells.Sort((dgvc1, dgvc2) =>
{
var rowCompare = dgvc1.RowIndex.CompareTo(dgvc2.RowIndex);
if (rowCompare != 0) return rowCompare;
else
{
return dgvc1.ColumnIndex.CompareTo(dgvc2.ColumnIndex);
}
});
if (clipboardElements.Count <= orderedSelectedCells.Count)
{
for (int i = 0; i < clipboardElements.Count; i++)
{
orderedSelectedCells[i].Value =
Convert.ChangeType(clipboardElements[i], orderedSelectedCells[i].ValueType);
}
}
int newColumnIndex = 0;
if (dgv.CurrentCell.ColumnIndex + 1 <= dgv.Columns.Count)
{
newColumnIndex = dgv.CurrentCell.ColumnIndex + 1;
}
dgv.CurrentCell = dgv[newColumnIndex, dgv.CurrentCell.RowIndex];
|
EditMode
EditOnKeyStrokeOrF2 : Mode par défaut, il faut double-cliquer sur une cellule pour l’éditer.
EditOnEnter : Dans ce mode il suffit de cliquer sur la cellule pour l’éditer. Par contre un clique sur le header d’une ligne édite la première cellule, ce qui empêche de supprimer la ligne.
EditOnEnter et suppression de ligne :
|
private void DGV_MouseClick(object sender, MouseEventArgs e)
{
DataGridView.HitTestInfo hitInfo = this.DGV.HitTest(e.X, e.Y);
if (hitInfo.Type == DataGridViewHitTestType.RowHeader)
{
this.DGV.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
this.DGV.EndEdit();
}
else
{
this.DGV.EditMode = DataGridViewEditMode.EditOnEnter;
}
}
|
Tester les données des cellules dès leurs saisies
La validation bloque l’utilisateur tant qu’il n’a pas saisie de valeur valide et affiche un message d’erreur.
|
private void dataGridView_CellValidating(object sender,
DataGridViewCellValidatingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
if (dgv.Columns[e.ColumnIndex] == "ColumnName")
{
if (string.IsNullOrEmpty(e.FormattedValue.ToString())
{
dgv.Rows[e.RowIndex].ErrorText = "Cell must not be empty";
e.Cancel = true;
}
}
}
private void cduDataGridView_CellEndEdit(object sender,
DataGridViewCellEventArgs e)
{
((DataGridView)sender).Rows[e.RowIndex].ErrorText = String.Empty;
}
|
ComboBox
L'événement SelectionChangeCommitted, à la différence des événements SelectedIndexChanged ou SelectedValueChanged, ne se produit que lorsque l'utilisateur et non le programme modifie la sélection de la liste déroulante.
Pop-up message
|
MessageBox.Show("message", "titre", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
|
Progress Bar et Timer
|
public partial class Form1 : Form
{
ToDO toDO;
public Form1()
{
progressBar1.Minimum = 1;
progressBar1.Maximum = 20;
progressBar1.Value = 1;
progressBar1.Step = 1;
toDO = new ToDO();
toDO.ReportStatusUpdated +=
new ToDO.Delegate(toDO_ReportStatusUpdated);
toDO.EndOfWork += new ToDO.Delegate(toDO_EndOfWork);
}
void toDO_EndOfWork()
{
button1.Text = "OK";
}
void toDO_ReportStatusUpdated()
{
progressBar1.PerformStep();
}
private void button1_Click(object sender, EventArgs e)
{
toDO.DoWork();
}
}
public class ToDO
{
public delegate void Delegate();
public event Delegate ReportStatusUpdated;
public event Delegate EndOfWork;
Timer timer;
int count = 1;
void timer_Tick(object sender, EventArgs e)
{
if (count++ > 19)
WorkFinished();
else
ReportStatusUpdated();
}
private void WorkFinished()
{
timer.Enabled = false;
EndOfWork();
}
public void DoWork()
{
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(timer_Tick);
timer.Enabled = true;
}
}
|