如何在用户控件中读取主窗体的属性

5
我写了一个用户控件MenuItem,继承自Form Label。我有一个BackgroundWorker线程,其IsBusy属性通过MainForm中的一个属性IsBackgroundBusy公开。如何从MenuItem用户控件中读取此属性?我目前正在使用Application.UseWaitCursor,并在backgroundworker中设置它,它可以完美地工作,但是我不想改变鼠标指针。这就是为什么我觉得设置一个属性会更好。以下是我MainForm中的代码:
public partial class MainForm : Form
{
    public bool IsBackgroundBusy
    {
        get
        {
            return bwRefreshGalleries.IsBusy;
        }
    }

这是我的用户控件代码:

public partial class MenuItem: Label
{
    private bool _disableIfBusy = false;

    [Description("Change color if Application.UseWaitCursor is True")]
    public bool DisableIfBusy
    {
        get
        {
            return _disableIfBusy;
        }

        set
        {
            _disableIfBusy = value;
        }
    }

    public MenuItem()
    {
        InitializeComponent();
    }

    protected override void OnMouseEnter( EventArgs e )
    {
        if ( Application.UseWaitCursor && _disableIfBusy )
        {
            this.BackColor = SystemColors.ControlDark;
        }
        else
        {
            this.BackColor = SystemColors.Control;
        }

        base.OnMouseEnter( e );
    }

你的问题的核心是如何从用户控件中访问表单吗?(https://dev59.com/eW7Xa4cB1Zd3GeqPrZEH) - ryanyuyu
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - RoadRacer524
是的,既然提到BackgroundWorker了...那可能不太好用。这就解释了为什么现在这是一个单独的问题。 - ryanyuyu
3
您可以始终创建一个接口,公开由您的 MainForm 实现并由您的 MenuItem 使用的 IsBackgroundBusy { get; } 属性。这样,您的 MainForm 就不会与您的 MenuItem 耦合在一起。 - Anthony
1
我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
显示剩余2条评论
1个回答

1
(注:我不确定您是否实际拥有一个。您展示的MenuItem类继承自Label而不是UserControl。当您实际上没有处理UserControl对象时,应该避免使用“usercontrol”或“user control”这一术语。)
在没有完整的代码示例的情况下,很难确定正确的解决方案。但是,假设您通常使用BackgroundWorker,那么您只需要控件的所有者(即包含的窗体)在更改时将必要的状态传递给控件即可。例如:
class MenuItem : Label
{
    public bool IsParentBusy { get; set; }
}

// I.e. some method where you are handling the BackgroundWorker
void button1_Click(object sender, EventArgs e)
{
    // ...some other initialization...

    bwRefreshGalleries.RunWorkerCompleted += (sender1, e1) =>
    {
        menuItem1.IsParentBusy = false;
    };

    menuItem1.ParentIsBusy = true;
    bwRefreshGalleries.RunAsync();
}

如果您已经有了RunWorkerCompleted事件的处理程序,那么只需将设置IsParentBusy属性的语句放在那里,而不是添加另一个处理程序。
然后,您可以查看IsParentBusy属性,而不是使用Application.UseWaitCursor属性。
还有其他机制可供使用; 我确实同意一般感觉是MenuItem控件不应绑定到您特定的Form子类。 如果由于某种原因上述方法不能在您的情况下起作用,则需要详细说明问题:提供一个好的代码示例,并明确解释为什么直接使控件的容器直接管理其状态对您不起作用。

感谢您澄清了我应该使用的术语来正确描述我的问题,同时也感谢您的回答。它完全实现了我想要的目标,只是采用了我没有考虑过的不同方法。然而,在设置(sender, e)时,我遇到了错误。无法在此范围内声明,因为它会赋予 'sender' 不同的含义。但是,如果我能让它工作,那么您指出的内容就非常完美了。 - RoadRacer524
我陷入了困境。我声明了一个“新”的发送器和事件参数(s,i),现在它完美地工作了。谢谢@Peter! - RoadRacer524
很高兴能够帮忙。抱歉打错了字……我会编辑帖子来修复它,以防其他人正在寻找类似的解决方案。很高兴你能自己找出我的错误。 :) - Peter Duniho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接