You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VideoControl自定义方法调用异常:实例调用无法正常播放视频

问题

我正在尝试为VideoControl.cs添加一个函数方法,以便从Form1.cs的按钮点击事件中调用,所用代码基于一个VLC播放器项目。

目前启动视频的方式是在窗体的videoControl1控件内右键,从右键菜单选择Load选项,该操作会触发VideoControl.cs中的loadFileToolStripMenuItem_Click函数,可正常播放视频。

我编写了一个public静态方法testingVid,期望直接传入视频路径无需文件选择弹窗,代码如下:

public static void testingVid(string theVideo)
{
    m_fileName = theVideo;
    m_lastPlayedIsFile = true;
    Play(out string outMessage);

    if (pCallback != null)
    {
        foreach (IVideoControl p in pCallback)
        {
            p.NotifyPlay(m_fileName, true);
        }
    }
}

从Form1.cs中以VideoControl.testingVid(@"C:\Users\Admin\Videos\a_test_video.mp4")调用时,出现CS0120错误:非静态字段、方法或属性需要对象引用。

改为创建类实例调用:

VideoControl VC = new VideoControl();
VC.testingVid(@"C:\Users\Admin\Videos\a_test_video.mp4");

无报错但无法像右键菜单那样正常播放视频,调试发现两种方式的最终数据一致,请问问题出在哪里?


问题原因及解决方法

1. 静态方法调用报错的原因

testingVid被定义为静态方法,但方法内直接访问了m_fileName、m_lastPlayedIsFile、pCallback这些非静态成员——这些成员属于VideoControl的实例对象,而非类本身,静态方法无法直接访问实例成员,因此触发CS0120错误。

2. 新建实例无法播放的原因

你新建的VideoControl实例VC是一个完全独立的控件对象,它没有被添加到窗体的控件树中,也和界面上已经显示的videoControl1控件没有任何关联。右键菜单触发的是已在窗体上初始化完成、与界面绑定的videoControl1实例的方法,两者不是同一个对象,所以新实例调用方法不会在界面上呈现播放效果。

正确实现方式

方式一:直接复用窗体上已有的videoControl1实例(推荐)

把testingVid改成非静态方法,去掉static关键字:

public void testingVid(string theVideo)
{
    m_fileName = theVideo;
    m_lastPlayedIsFile = true;
    Play(out string outMessage);

    if (pCallback != null)
    {
        foreach (IVideoControl p in pCallback)
        {
            p.NotifyPlay(m_fileName, true);
        }
    }
}

然后在Form1.cs的按钮点击事件中,直接调用界面上已有的videoControl1控件的方法:

videoControl1.testingVid(@"C:\Users\Admin\Videos\a_test_video.mp4");

这种方式和右键菜单的逻辑完全一致,操作的是同一个控件实例,就能正常播放视频。

方式二:静态方法调用(仅单实例场景适用)

如果一定要用静态方法,可以在VideoControl类中维护一个静态实例引用,用于指向窗体上的videoControl1:

// 在VideoControl类中添加静态实例引用
public static VideoControl CurrentInstance { get; private set; }

// 在VideoControl的构造函数中赋值
public VideoControl()
{
    InitializeComponent();
    CurrentInstance = this;
}

// 修改静态方法,通过静态引用访问实例成员
public static void testingVid(string theVideo)
{
    if (CurrentInstance == null) return;
    
    CurrentInstance.m_fileName = theVideo;
    CurrentInstance.m_lastPlayedIsFile = true;
    CurrentInstance.Play(out string outMessage);

    if (CurrentInstance.pCallback != null)
    {
        foreach (IVideoControl p in CurrentInstance.pCallback)
        {
            p.NotifyPlay(CurrentInstance.m_fileName, true);
        }
    }
}

之后在Form1.cs中直接调用静态方法即可:

VideoControl.testingVid(@"C:\Users\Admin\Videos\a_test_video.mp4");

注意:这种方式仅适用于窗体中只有一个VideoControl实例的场景,多实例场景会出现逻辑混乱。


内容的提问来源于stack exchange,提问作者StealthRT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:18:31