Version du 7 septembre 2011 à 09:43
É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:
Fichier:Csharp.png
|
private void Form_Load(object sender, EventArgs e)
{
ElementA.BringToFront();
|
Centrer un Label
AutoSize → False
TextAlign → MiddleCenter
Simuler une entrée au clavier
[1]
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.
Fichier:Csharp.png
|
// récupération du control contenant le menu contextuel
private void tsmi_Click(object sender, EventArgs e)
{
var menu = (ToolStripDropDownItem)sender;
var strip = (ContextMenuStrip)menu.Owner;
// SourceControl est null lors de l'utilisation des raccourcis clavier
var control = (DataGridView)strip.SourceControl;
// Dans ce cas et si le control n'est pas dans un SplitContainer
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.
Fichier:Csharp.png
|
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.
Fichier:Csharp.png
|
Thread thread = new Thread(new ThreadStart(delegate()
{ // code qui doit être réalisé par le thread de calcul }));
// ou
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é.
Fichier:Csharp.png
|
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)
{
// InvokeRequired compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.button.InvokeRequired)
{ // calls itself asynchronously
mainFormCallback callback = new mainFormCallback(SetText);
this.Invoke(callback, text);
}
else
{
button.Text = text;
}
}
}
|
[2]
DataGridView
Coller des données provenant d'Excel
Fichier:Csharp.png
|
// récupération du contenu du presse papier
string clipboardText = Clipboard.GetText();
// séparation par lignes et suppression des lignes vides
string[] clipboardLines = clipboardText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
// séparation par cellules afin de connaitre le nombre d'éléments à coller
var clipboardElements = new List<string>();
foreach (var line in clipboardLines)
{
clipboardElements.AddRange(line.Split('\t'));
}
// trie des éléments dans l'ordre croissant car les SelectedCells sont dans l'ordre de la sélection
// si elle s'est faite de gauche à droite et/ou de haut en bas
// les cellules sont en ordre décroissant d'index
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);
}
});
// seulement si le nombre d'éléments à copier est <= à l'espace sélectionné pour la copie
if (clipboardElements.Count <= orderedSelectedCells.Count)
{
for (int i = 0; i < clipboardElements.Count; i++)
{
orderedSelectedCells[i].Value =
Convert.ChangeType(clipboardElements[i], orderedSelectedCells[i].ValueType);
}
}
// si le mode d'édition est EditOnEnter, la dernière cellule collée est toujours en édition
// et son contenu visuellement pas à jour.
// pour corrigé ça on déplace le focus sur la cellule suivante ou sur la première
int newColumnIndex = 0;
if (dgv.CurrentCell.ColumnIndex + 1 <= dgv.Columns.Count)
{
newColumnIndex = dgv.CurrentCell.ColumnIndex + 1;
}
// cette ligne peut générer une exception si la cellule est hidden
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 :
Fichier:Csharp.png
|
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.
Fichier:Csharp.png
|
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
Fichier:Csharp.png
|
MessageBox.Show("message", "titre", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
|
Progress Bar et Timer
Fichier:Csharp.png
|
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;
}
}
|