线程写入各自列表框的多个用户控件
本文关键字:用户 控件 列表 线程 | 更新日期: 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
方法。