Avatar billede Loafers Nybegynder
06. januar 2013 - 16:17 Der er 17 kommentarer og
1 løsning

Problemer med contextMenu og object sender

Jeg er en glad selvlært programmør, som i mange år har brugt VB6. Nu er det så tid til at benytte C#. Stejl omlæringskurve :)

Så jeg har 52 labels i main form på en Windows Form Application (label1, label2, label3 etc.)som jeg fylder med navne.
Hver label er koblet til den samme contextMenu med et antal valgmuligheder (f.eks. Fri, Til stede, Ferie).
Nu vil jeg gerne have at jeg kan højreklikke på en label og via den ændre en værdi i et tilhørende array (jeg har f.eks. oprettet public static string[] statusFarve = new string[53];).


private void friToolStripMenuItem_Click(object sender, EventArgs e)
{
    ToolStripMenuItem tsmi = (ToolStripMenuItem)sender;
    this.textBox1.Text = tsmi.Text; //textBox1 er til testformål
}


giver mig desværre kun teksten fra menupunktet (her "Fri"), og jeg har brug for enten at referere til label[index].Text eller til selve index og en metode til at sætte statusFarve[index]="0".

Fri skal sætte værdien til "0", Til stede = "2" og Fri = "3".

Med normalord,
så skal et klik på contextMenuItempunktet "Fri" i label1 sætte en variabel statusFarve1 til værdien "0".
label15 skal sætte værdien i statusFarve15.

og et klik på contextMenuItempunktet "Til stede" i label1 sætte en variabel statusFarve1 til værdien "1".
label15 skal sætte værdien i statusFarve15.

Og det nytter desværre ikke at være meget generel. Jeg lærer desværre bedst med et eksempel fyldt med data, som jeg kender.

Jeg har tumlet med dette problem i lang tid nu, og jeg har stadig ikke fattet de eksempler jeg kan finde på nettet og heller ikke fra bogen af Andrew Troelsen: Pro C# 2008 and the .NET 3.5 Platform", som jeg købte netop for at lære og forstå via en dygtig lærer.
Jeg er bange for at mine mange år med VB6 har sat sine spor og jeg har ganske svært ved at omstille mig.
Avatar billede olebole Juniormester
06. januar 2013 - 17:37 #1
<ole>

Der er en hel del forskel på kontrollernes opbygning, sammenlignet med VB6. Prøv:

private void friToolStripMenuItem_Click(object sender, EventArgs e)
{
    ToolStripMenuItem item = sender as ToolStripMenuItem;
    if (item != null)
    {
        int index = (item.OwnerItem as ToolStripMenuItem).DropDownItems.IndexOf(item);
        this.textBox1.Text = index.ToString();
    }
}

/mvh
</bole>
Avatar billede Loafers Nybegynder
06. januar 2013 - 21:24 #2
Tusind tak for svaret. Jeg er så ikke den eneste der hygger mig her en søndag aften.

Men desværre. Nu får jeg fejlmeddelelsen:

"An unhandled exception of type 'System.NullReferenceException' occurred in Maido.exe

Additional information: Objektreferencen er ikke indstillet til en forekomst af et objekt."
Avatar billede olebole Juniormester
06. januar 2013 - 22:09 #3
Jeg kan ikke umiddelbart se hvilke fejl, du laver. Koden ovenfor fungerer fint for mig  =)

Ligger dine ToolStripMenuItems i en menuStrip - eller?
Avatar billede Loafers Nybegynder
07. januar 2013 - 15:58 #4
Jeg har lavet mine labels og trukket en ContextMenuStrip ind i min form. Her har jeg så lavet x antal menupunkter. Når jeg dobbeltklikker på menupunktet "fri", får jeg en
private void friToolstripMenuItem_Click(object sender EventArgs e)

Når jeg indsætter din kode i den får jeg den omtalte fejl.

Når jeg opretter en testform med dette ene formål for at test ser den således ud


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace menutest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void friToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            if (item != null)
            {
                int index = (item.OwnerItem as ToolStripMenuItem).DropDownItems.IndexOf(item);
                this.textBox1.Text = index.ToString();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}


Og her får jeg samme fejl.

"An unhandled exception of type 'System.NullReferenceException' occurred in Maido.exe

Additional information: Objektreferencen er ikke indstillet til en forekomst af et objekt."
Avatar billede Loafers Nybegynder
07. januar 2013 - 16:22 #5
UPS!
Bare for at jeg ikke skal virke helt åndsforstyrret:

Den korrekte fejlkode på testen er selvfølgelig:

"An unhandled exception of type 'System.NullReferenceException' occurred in menutest.exe

Additional information: Objektreferencen er ikke indstillet til en forekomst af et objekt."
Avatar billede olebole Juniormester
07. januar 2013 - 16:27 #6
Ahhh ... en ContextMenuStrip! Så er skal IF'en se sådan ud:

            if (item != null)
            {
                int index = (item.Owner as ToolStrip).Items.IndexOf(item);
                this.textBox1.Text = index.ToString();
            }
Avatar billede Loafers Nybegynder
07. januar 2013 - 16:51 #7
AH!

Tusind tak.
Hvade du ikke heddet Ole og jeg ikke var en mand, så havde du fortjent et et trutkys.

Nu må du nøjes med en dybfølt tak.

Hvordan er det nu lige, at du får de der point?
Avatar billede olebole Juniormester
07. januar 2013 - 17:17 #8
*LoL* Jeg klarer mig fint med takken  *D

Man kan vælge at markere et indlæg som henholdsvis en kommentar (default) eller et svar. Kun svar kan tildeles point.

De fleste 'gamle' brugere vælger at nøjes med kommentarer, indtil det viser sig, om spørger kunne bruge ens bidrag til noget. Er det tilfældet - eller hvis en bruger har svedt godt med forsøg på hjælp - er det kotume, at spørger beder den eller de pågældende bruger(e) lægge et svar, så point kan fordeles.

Jeg har ikke samlet point de seneste par år, så det bliver ikke denne gang, du får lov at prøve det. I stedet lægger du selv et svar og accepterer det, hvorved tråden lukkes  =)
Avatar billede Loafers Nybegynder
07. januar 2013 - 17:20 #9
Jeg holder lige kysset. I min begejstring (ikke at dit svar ikke er brugbart), så fik jeg lige overset at jeg ganske rigtigt får et index, men det er index på menupunkterne. Jeg skulle helst have nummeret på den label, der benytter contextMenuen når den kaldes.

Altså om det er label1 eller label 2 eller 15, der kalder menuen.
Avatar billede olebole Juniormester
07. januar 2013 - 17:32 #10
Det skulle også gerne være tilfældet  =)
Avatar billede olebole Juniormester
07. januar 2013 - 17:34 #11
Nååhhh ... nu forstår jeg! Det tror jeg ikke umiddelbart, du kan hente ud ved klik på et menupunkt. Der er tale om to forskellige events
Avatar billede Loafers Nybegynder
07. januar 2013 - 17:53 #12
OK!
Tak for indsatsen.

Jeg lukker og slukker.
Avatar billede olebole Juniormester
07. januar 2013 - 18:06 #13
Du kan gøre noget andet. På dine labels lægger du handlers som denne:

        private void label1_Click(object sender, EventArgs e)
        {
            Label item = sender as Label;
            contextMenuStrip1.Tag = item.Name;
            contextMenuStrip1.Show(Cursor.Position.X, Cursor.Position.Y);
        }

Så sætter du din contextmenus tag property til din labels name. Nu kan du skrive sådan i IF'erne i ToolStripMenuItem handlerne:

            if (item != null)
            {
                this.textBox1.Text = item.Owner.Tag.ToString();
            }

Så burde du få udskrevet navnet på den label, der åbnede menuen
Avatar billede olebole Juniormester
07. januar 2013 - 18:08 #14
Vil du så snave alligevel?  :D
Avatar billede olebole Juniormester
07. januar 2013 - 18:28 #15
- og hvis du ikke åbner menuen med din egen handler, men sætter den via dine labels ContextMenuStrip property, kan du bruge en handler som denne:

        private void friToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            if (item != null)
            {
                ContextMenuStrip owner = item.Owner as ContextMenuStrip;
                if (owner != null)
                {
                    this.textBox1.Text = owner.SourceControl.Name.ToString();
                }
            }
        }
Avatar billede Loafers Nybegynder
12. januar 2013 - 21:09 #16
"SNAVE"
Tror du jeg hedder Polle?

Jeg sagde trutkys!

Og da du har gjort dig den ulejlighed at tænke videre på mit problem, og ovenikøbet ser ud til at have løst det, så er du da velkommen til at betragte kysset som afsendt. Du kan afhente det i CyberSpace. Hvordan du får det videre ind i MeatSpace véd jeg ikke.

Tusind tak.
Avatar billede olebole Juniormester
12. januar 2013 - 21:37 #17
*LoL* Selvtak  :D
Avatar billede Loafers Nybegynder
12. januar 2013 - 22:06 #18
Og for dem, der spændt har fulgt denne tråd :)

De to events ser således ud i min testopsætning, der ser ud til at virke fuldstændig efter hensigten:


        private void label52_RightClick(object sender, EventArgs e)
        {
            Label item = sender as Label;

                contextMenuStrip1.Tag = item.Name;
                contextMenuStrip1.Show(Cursor.Position.X, Cursor.Position.Y);
        }

        private void test1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Tak til olebole fra Eksperten.dk for hjælpen
            ToolStripMenuItem item = sender as ToolStripMenuItem;

            if (item != null)
            {
                // LabelIndex sættes med Substring så jeg får
                // labelnummer separeret ud
                int LabelIndex = Convert.ToInt32(item.Owner.Tag.ToString().Substring(5));
               
                // timer1LoadStatusFile disables, så jeg ikke skriver
                //og læser fra statusfilen på samme tid.
                timer1LoadStatusFile.Enabled = false;
               
                // Sæt den relevante globale vaariabel MINUS 1, da array starter på 0
                //og labels starter på 1
                Module1.hvilkenAfdeling[LabelIndex - 1] = "1";
               
                // I writeStatusfile genstartes timer1LoadStatusFile efter at filen er lukket
                writeStatusFile();
               
                // alle label populeres med opdatererede oplysninger
                LoadNameBoxes();
            }
        }
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester