如何解决C#中的“ InvalidCastException”?

时间:2019-01-05 18:32:29

标签: c# forms casting picturebox

我遇到一个运行时错误,通知我它无法将PictureBox类型的对象强制转换为MusicNote类型(MusicNote继承自PictureBox。)

private void Note_MouseDown(object sender, MouseEventArgs e)
    {
        //try
        //{
            foreach (MusicNote mn in panel2.Controls) //this is where the error occurs
            {
                if (sender == mn)
                {
                    if (e.Button == MouseButtons.Right)
                    {
                        count = 0;
                        timer1.Start();
                        sp.SoundLocation = MusicNote_path + mn.note + ".wav";
                        sp.Play();
                    }
                if (e.Button == MouseButtons.Left)
                {
                    dragging = true;
                    mn.BackColor = Color.HotPink;


                }

下面是MusicNote类的一部分,包括构造函数,用于显示每次构造MusicNote时发生的情况:

class MusicNote : PictureBox
{
    public int notepitch;
    public int noteduration;
    public String noteshape;
    public String note;
    enum Accid { sharp, flat, sole };

    public static String NoteImage_path = Environment.CurrentDirectory + @"\Notes-Images\\";
    public static int xLoc = 30;
    public int yLoc = 0;

    System.Timers.Timer timer1 = new System.Timers.Timer();

    public MusicNote(int iNotepitch, int iDuration, String iBnoteShape, String iNote)
    {
        notepitch = iNotepitch;
        noteduration = iDuration;
        noteshape = iBnoteShape;
        note = iNote;


        ImageLocation =  NoteImage_path + noteshape + ".bmp";
        BackColor = Color.Transparent;
        ClientSize = new Size(35, 35);
        //BringToFront();


        Location = new Point(xLoc, getyLoc(iNote));
        xLoc += 37;
    }

这是填充面板的方式:

MusicNote mn = new MusicNote(mk.getMusicNote(), duration, bNoteShape, mk.getNote());
mn.MouseDown += new MouseEventHandler(Note_MouseDown);
mn.MouseUp += new MouseEventHandler(Note_MouseUp);
mn.MouseClick += new MouseEventHandler(Note_MouseClick);

panel2.Controls.Add(mn); //adding MusicNote component to MusicStaff (panel2) collection

编辑:您可以查看错误here

感谢您的帮助。

5 个答案:

答案 0 :(得分:2)

要仅循环(println (get my-map 0)) 个实例,可以使用LINQ的df.description_data.str[1:-1].str.replace("'",'').str.split(' ') 0 [manage, musical, staffmanage, staff, music, c... Name: description_data, dtype: object 扩展方法:

MusicNote

答案 1 :(得分:1)

当程序在CREATE TABLE scores ( student_id SERIAL PRIMARY KEY, name VARCHAR(100), test1 INTEGER, test2 INTEGER, test3 INTEGER, test4 INTEGER, highest_score VARCHAR(50) ) 这样的事件处理程序中获得控件时,您会收到对该控件的引用,该控件在UI(Note_MouseDown)中“捕获”了该事件。

尝试使用object sender子句将sender强制转换为MusicNote。如果无法进行强制转换(因为as不是sender的原因),则使用MusicNote子句不会引发异常-而是为您提供NULL引用,您可以进行测试。

尝试这样的事情:

as

您真的不需要private void Note_MouseDown(object sender, MouseEventArgs e) { var mn = sender as MusicNote; if (mn != null) { if (e.Button == MouseButtons.Right) { count = 0; mn.timer1.Start(); sp.SoundLocation = MusicNote_path + mn.note + ".wav"; sp.Play(); } if (e.Button == MouseButtons.Left) { dragging = true; mn.BackColor = Color.HotPink; } } }

答案 2 :(得分:0)

每次foreach (MusicNote mn in panel2.Controls)循环找到除MusicNote之后的其他内容时,都会发生此错误。

您可以通过循环Controls之类的所有foreach (Control cntrl in panel2.Controls)来避免这种情况

示例代码:

foreach (Control cntrl in panel2.Controls) 
            {
                if(cntrl is MusicNote)
                {
                     //do something with the MusicNote Control
                }
            }

答案 3 :(得分:0)

有很多方法可以解决您的问题,但是让我们看一下代码,以便了解它的笨拙之处。用简单的英语来说,您正在这样做:

  

在控件上按下鼠标按钮。哪个控件?好了sender中的控件。您遍历panel2中的所有控件以查看其中是否是sender,然后执行一些工作。

但是为什么要遍历panel2中的所有控件?在创建MusicNote控件时,您专门为该控件创建了此事件处理程序,以在鼠标按下时通知您。现在控件正在引发一个事件,并说:“嘿,鼠标按钮按下了,它压在我身上了!”您看到,即使panel2.Controls.OfType<MusicNote>()可以解决您的问题,但是为什么要这样做呢?好像是XY problem

执行操作的唯一原因是创建了控件,订阅了MouseDown事件,然后以编程方式将控件从一个面板移至另一个面板,并且您只想在以下情况下做一些工作:鼠标按下时,控件恰好位于panel2中。我怀疑你搬走了;即使这样做,也有更好的方法来处理这种情况。

正确的解决方案

您不需要循环,只需要这样:

private void Note_MouseDown(object sender, MouseEventArgs e)
{
    // If neither right nor left is down, return immediately because nothing needs 
    // to be done.
    if (!(e.Button == MouseButtons.Right || e.Button == MouseButtons.Left))
    {
        return;
    }

    // This should not fail, if it does, then ask yourself why have you created 
    // this handler for things which are not MusicNote.
    MusicNote mn = (MusicNote)sender;

    // Do some work below
    if (e.Button == MouseButtons.Right)
    {
        count = 0;
        timer1.Start();
        sp.SoundLocation = MusicNote_path + mn.note + ".wav";
        sp.Play();
    }

    if (e.Button == MouseButtons.Left)
    {
        dragging = true;
        mn.BackColor = Color.HotPink;
    }
}

答案 4 :(得分:-1)

project.dataset.your_table_copy不仅包含panel2.ControlsControls类型的MusicNote时,将发生此错误。从您的数据尚不清楚所有PictureBox的类型是什么,应该完全是PictureBoxes的panel2.ControlsCollection。如果List包含与panel2.ControlsControl不同类型的任何Picturebox(例如MusicNote等),则会出现错误。如果所有TextBox的类型都是正确的,则很可能在发生错误时未完全加载panel2.Controls。 您可以尝试:

panel2
相关问题