Je suis bloqué dans les formulaires Windows .NET 2.0.
Il ne semble pas que la possibilité de sélectionner plusieurs nœuds existe dans le contrôle standard TreeView
.
J'essaie de le faire pour une sélection de menu contextuel. Ainsi, les cases à cocher ne sont pas un paradigme UI acceptable ici.
Quelle est la meilleure façon de fournir cette fonctionnalité très nécessaire?
Nous l'avons fait dans un projet WTL une fois, mais le travail de base nécessaire est le même pour .NET. Pour obtenir un contrôle d'arborescence de sélection multiple, vous devrez dessiner vous-même les objets d'arborescence et remplacer la manipulation du clavier et de la souris. Vous devrez également conserver votre propre liste d'éléments sélectionnés.
N'oubliez pas d'envisager des règles de sélection (les parents et les enfants et les enfants sont-ils autorisés, par exemple), et n'oubliez pas de mettre en œuvre les raccourcis clavier, y compris la sélection à l'aide de Ctrl, de décalage et de Ctrl + Shift, ainsi que la barre d'espace pour la sélection/la désélectionner .
Sont des cases à cocher une option? OU VOULEZ-VOUS THE SELECT QUE VOUS INSTRUCTEZ UNE BOITE DE LISTE?
Il existe un contrôle d'arborescence multi-sélection disponible sur CODEPROJECTION: Vue d'arborescence multi-sélection
Le code ci-dessous vous permettra de régler la couleur d'arrière-plan que vous utilisez pour vous assurer que tous les nœuds sélectionnés sont mis en surbrillance.
protected override void WndProc(ref Message m)
{
switch (m.Msg) {
// WM_REFLECT is added because WM_NOTIFY is normally sent just
// to the parent window, but Windows.Form will reflect it back
// to us, MFC-style.
case Win32.WM_REFLECT + Win32.WM_NOTIFY: {
Win32.NMHDR nmhdr = (Win32.NMHDR)m.GetLParam(typeof(Win32.NMHDR));
switch((int)nmhdr.code) {
case Win32.NM_CUSTOMDRAW:
base.WndProc(ref m);
Win32.NMTVCUSTOMDRAW nmTvDraw = (Win32.NMTVCUSTOMDRAW)m.GetLParam(typeof(Win32.NMTVCUSTOMDRAW));
switch (nmTvDraw.nmcd.dwDrawStage) {
case Win32.CDDS_ITEMPREPAINT:
// Find the node being painted.
TreeNode n = TreeNode.FromHandle(this, nmTvDraw.nmcd.lItemlParam);
if (allSelected.Contains(n))
// Override its background colour.
nmTvDraw.clrTextBk = ColorTranslator.ToWin32(SystemColors.Highlight);
m.Result = (IntPtr)Win32.CDRF_DODEFAULT; // Continue rest of painting as normal
break;
}
Marshal.StructureToPtr(nmTvDraw, m.LParam, false); // copy changes back
return;
}
break;
}
}
base.WndProc(ref m);
}
// WM_NOTIFY notification message header.
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public class NMHDR
{
private IntPtr hwndFrom;
public IntPtr idFrom;
public uint code;
}
[StructLayout(LayoutKind.Sequential)]
public struct NMCUSTOMDRAW
{
public NMHDR hdr;
public int dwDrawStage;
public IntPtr hdc;
public RECT rc;
public IntPtr dwItemSpec;
public int uItemState;
public IntPtr lItemlParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct NMTVCUSTOMDRAW
{
public NMCUSTOMDRAW nmcd;
public int clrText;
public int clrTextBk;
public int iLevel;
}
public const int CDIS_SELECTED = 0x0001;
public const int CDIS_FOCUS = 0x0010;
public const int CDDS_PREPAINT = 0x00000001;
public const int CDDS_POSTPAINT = 0x00000002;
public const int CDDS_PREERASE = 0x00000003;
public const int CDDS_POSTERASE = 0x00000004;
public const int CDDS_ITEM = 0x00010000; // item specific
public const int CDDS_ITEMPREPAINT = (CDDS_ITEM | CDDS_PREPAINT);
public const int CDDS_ITEMPOSTPAINT = (CDDS_ITEM | CDDS_POSTPAINT);
public const int CDDS_ITEMPREERASE = (CDDS_ITEM | CDDS_PREERASE);
public const int CDDS_ITEMPOSTERASE = (CDDS_ITEM | CDDS_POSTERASE);
public const int CDDS_SUBITEM = 0x00020000;
public const int CDRF_DODEFAULT = 0x00000000;
public const int CDRF_NOTIFYITEMDRAW = 0x00000020;
public const int CDRF_NOTIFYSUBITEMDRAW = 0x00000020; // flags are the same, we can distinguish by context
public const int WM_USER = 0x0400;
public const int WM_NOTIFY = 0x4E;
public const int WM_REFLECT = WM_USER + 0x1C00;
Vous pourriez regarder une solution tierce. L'arbre Infragistics cela. Pas gratuit, mais le temps passé à essayer de trouver une solution n'est pas vraiment gratuit, non plus.
La solution la plus simple consisterait à étendre le contrôle existant de l'arborescence expédié avec le cadre et remplacer les méthodes ONBEFORFORESELLECT et ONAFterSélectionnez avec la logique pour capturer plusieurs sélections.
Un exemple peut être trouvé ici: http://www.arstdesign.com/articles/treeviewnms.html