winforms C# -在不同线程中添加UserControl导致异常,即使在调用后也是如此

vsdwdz23  于 2023-01-02  发布在  C#
关注(0)|答案(1)|浏览(158)

我在WinForms中构建了一个自定义UserControl,并通过一个辅助线程将其添加到Panel中。
我知道当通过辅助线程添加控制时,您需要调用主线程来完成它。所以我这样做了..但我仍然收到一个异常,显示“跨线程操作无效:控件“pictureBoxImage”是从创建它的线程以外的线程访问的。”
我被卡住了,不知道是什么原因导致了这个问题,因为我试图通过在我的每个自定义UserControl方法上放置一个断点来调试它,但是它们中的任何一个都没有抛出异常。

private void addControl(Control i_ControllToAdd, Control i_ParentControl)
    {
        if (i_ParentControl.InvokeRequired)
        {
            i_ParentControl.Invoke(new Action(() => addControl(i_ControllToAdd, i_ParentControl)));
            return;
        }

        i_ParentControl.Controls.Add(i_ControllToAdd);
    }

这是自定义UserControl类

public partial class FBPostUserControl : UserControl
    {
        private readonly string m_UserName = string.Empty;
        private readonly Image m_UserProfileImage = null;
        private readonly DateTime? m_DatePosted = null;
        private Image m_Image = null;
        private string m_PostBody = string.Empty;

    public string UserName
    {
        get { return m_UserName; }
    }

    public DateTime? DatePosted
    {
        get { return m_DatePosted; }
    }

    public Image Image
    {
        get { return m_Image; }
        set
        {
            if (value == null)
            {
                pictureBoxImage.Visible = false;
            }
            else
            {
                pictureBoxImage.Visible = true;
                pictureBoxImage.Image = value;
                updateImageSize();
            }
        }
    }

    private void updateImageSize()
    {
        if (pictureBoxImage.Image != null)
        {
            double ratio = pictureBoxImage.Image.Width / pictureBoxImage.Image.Height;
            pictureBoxImage.Height = (int)(pictureBoxImage.Width / ratio);
            pictureBoxImage.SizeMode = PictureBoxSizeMode.Zoom;
        }
    }

    public string PostBody
    {
        get { return m_PostBody; }
        set
        {
            if (string.IsNullOrWhiteSpace(value) == false)
            {
                labelPostBody.Visible = true;
                labelPostBody.Text = value;
            }
            else
            {
                labelPostBody.Visible = false;
            }
        }
    }

    public Image UserProfileImage
    {
        get { return m_UserProfileImage; }
    }

    public FBPostUserControl(string i_Name, Image i_ProfileImage, DateTime? i_PostDate)
    {
        InitializeComponent();
        m_UserName = i_Name;
        m_UserProfileImage = i_ProfileImage;
        m_DatePosted = i_PostDate;

        refreshHeader();
    }

    private void refreshHeader()
    {
        pictureBoxUserImage.Image = m_UserProfileImage;
        labelName.Text = m_UserName;

        if (labelDate != null)
        {
            labelDate.Text = m_DatePosted.ToString();
        }
        else
        {
            labelDate.Visible = false;
        }
    }
}
ql3eal8s

ql3eal8s1#

任何控件都应在UI线程上创建,还应从同一线程访问。
它给你异常的原因是因为你在一个线程(你的辅助线程)上创建你的ControlToAdd,并通过使用Invoke语句将它添加到另一个线程(你的UI线程)上的UI。
要消除这种情况,请确保在一个线程上创建控件,并在创建控件的同一个线程上访问它。
下面的片段可能不是你想要的,但它只是给予你一个想法;

i_ParentControl.Invoke(new Action(() => addControl(new Control(), i_ParentControl)));

相关问题