线程写入各自列表框的多个用户控件

本文关键字:用户 控件 列表 线程 | 更新日期: 2023-09-27 17:58:53

我在一个应用程序中使用4个WPF用户控件。每个用户控件都启动自己的线程来做一些事情,最后我希望它们只更新各自用户控件中的ListBox。

我尝试在用户控件代码中使用一个静态变量来保存用户控件的实例,甚至是它的ListBox,但这只会导致(错误的线程)只写入最后一个用户控件ListBox。

我甚至试过这种

private static ListBox1 = null;
private static ListBox2 = null;
private static ListBox3 = null;
private static ListBox4 = null;
private static ListBoxToUse;

然后在初始化每个UserControl 时

if (ListBox1 == null)
{
    ListBox1 = this;
    ListToUse = this;
}
else if (ListBox2 == null)
{
    ListBox2 = this;
    ListToUse = this;
} ...

然后

ListBoxToUse.Dispatcher.BeginInvoke(new Action(delegate()
{
    ListBoxToUse.Items.Add("......");
}));

但这也没用。有什么建议吗?

编辑1:-

以下是我的线程代码

    private class CopyPortDevFileThread
    {
        public MyWorkingDirectoryInfo WorkingDirectory { get; set; }
        public PortableDeviceFile PortDevFileToCopy { get; set; }
        public string DestinationDir { get; set; }
        public void CopyFile()
        {
            Debug.WriteLine("CopyFile DestinationDir " + DestinationDir);
            // To fix Samsung NT-7000 bug of giving the Id when Path.GetFilename() is called
            string gfn = Path.GetFileName(PortDevFileToCopy.Id);
            string fn = DestinationDir + "''" + gfn;
            WorkingDirectory.USBDevice.DownloadFile(PortDevFileToCopy, DestinationDir);
            if (!IsValidFilename(gfn))
            {
                // Rename file if name is okay
                if (IsValidFilename(PortDevFileToCopy.Name))
                {
                    int sec = 5;
                    while (sec > 0)
                    {
                        if (IsFileReady(fn))
                        {
                            File.Move(fn, Path.Combine(DestinationDir, PortDevFileToCopy.Name));
                            fn = Path.Combine(DestinationDir, PortDevFileToCopy.Name);
                            sec = 0;
                        }
                        else
                        {
                            Console.WriteLine("Waiting .....");
                            System.Threading.Thread.Sleep(1000);
                        }
                        sec -= 1;
                    }
                }
            }
        }
    }

然后从用户控制的代码调用线程

    private void CopyPortDevDocument(PortableDeviceFile _file, string _destDir)
    {
        Debug.WriteLine("CopyPortDevDocument with destination directory " + _destDir);
        if (_file == null)
        {
            return;
        }
        if (_destDir == null)
        {
            return;
        }
        if ((System.IO.Directory.Exists(_destDir)))
        {
            CopyPortDevFileThread cpdft = new CopyPortDevFileThread();
            cpdft.WorkingDirectory = Pwd;
            cpdft.PortDevFileToCopy = _file;
            cpdft.DestinationDir = _destDir;
            Thread cpdfThread = new Thread(new ThreadStart(cpdft.CopyFile));
            cpdfThread.Start();
            LogOutput(@"creating " + _destDir + "''" + _file.Name);
        }
    }

线程写入各自列表框的多个用户控件

您不需要这些静态字段。只需在UserControl XAML中分配ListBox控件的x:Name属性。然后,您可以作为UserControl类的成员访问ListBox:

<UserControl x:Class="UserControlTest.MyUserControl" ...>
    <Grid>
        <ListBox x:Name="list" .../>
        ...
    </Grid>
</UserControl>

上面的XAML在类MyUserControl中创建了一个类型为ListBox的字段list


更新:更改线程类的CopyFile方法,使其接受object类型的参数,然后将该对象强制转换为UserControl引用:

public void CopyFile(object parameter)
{
    var userControl = parameter as MyUserControl;
    ...
}

然后使用UserControl参考参数启动线程,如下所示:

var cpdfThread = new Thread(new ParameterizedThreadStart(cpdft.CopyFile));
cpdfThread.Start(this); // where this is the UserControl reference

另一种选择是将UserControl引用作为属性添加到CopyPortDevFileThread类中。

您也可以通过调用ThreadPool.QueueUserWorkItem来使用ThreadPool线程,而不是创建一个新的线程来执行CopyFile方法。