为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
扬帆大鱼 2022-07-10 10:19:52
我收到一个运行时错误,它告诉我它无法将 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;    }任何帮助表示赞赏,谢谢。
查看完整描述

4 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

要仅循环MusicNote实例,您可以使用OfTypeLINQ 中的扩展方法:


foreach (MusicNote mn in panel2.Controls.OfType<MusicNote>()) {

   // do stuff


查看完整回答
反对 回复 2022-07-10
?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

当您的程序在事件处理程序中获得控制权时,例如您收到对在 UI ( )Note_MouseDown中“获取”事件的控件的引用。object sender


尝试使用该子句强制转换sender为。如果无法进行强制转换(因为不是),则使用该子句不会引发异常——相反,它只会为您提供一个 NULL 引用,您可以对其进行测试。MusicNoteassenderMusicNoteas


尝试这样的事情:


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;

        }

    }

}

你真的不需要foreach.


查看完整回答
反对 回复 2022-07-10
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

有很多方法可以解决您的问题,但让我们对您的代码进行一次演练,以便您了解它的笨拙程度。用简单的英语,你正在这样做:


在控件上按下鼠标按钮。哪个控制?以及中的控制sender。您循环访问所有控件panel2以查看其中是否有一个,sender然后您进行一些工作。


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


你会做你正在做的事情的唯一原因是,如果你创建了控件,订阅了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;

    }

}


查看完整回答
反对 回复 2022-07-10
?
万千封印

TA贡献1891条经验 获得超3个赞

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


你可以通过循环来避免这种Controls情况foreach (Control cntrl in panel2.Controls)


示例代码:


foreach (Control cntrl in panel2.Controls) 

            {

                if(cntrl is MusicNote)

                {

                     //do something with the MusicNote Control

                }

            }


查看完整回答
反对 回复 2022-07-10
  • 4 回答
  • 0 关注
  • 182 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号