我在wpf c#中创建了一个程序。 我做了一个拖放处理程序,它将一些项添加到列表框中。虽然程序正在这样做(需要一些时间),但我希望Grid将其属性visiblity更改为visible,我想更新文本框以向用户显示正在处理的文件。代码如下:
更新:解决方案实施尝试
BackgroundWorker bgWorker = new BackgroundWorker();
private void Dropaudio(object sender, System.Windows.DragEventArgs e)
{
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.ProgressChanged +=
new ProgressChangedEventHandler(bgWorker_ProgressChanged);
bgWorker.WorkerReportsProgress = true;
this.Drop += new DragEventHandler(Dropaudio);
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
List<string> Jobs = new List<string>(droppedFilePaths);
bgWorker.RunWorkerAsync(Jobs);
}
}
void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.ProgressPercentage == 0)
{
Addingcues.Visibility = Visibility.Visible;
}
addcuepath.Text = e.UserState.ToString();
}
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
List<string> Jobs = e.Argument as List<string>;
bgWorker.ReportProgress(0, "Processing Data");
double count = 0;
double total = Jobs.Length;
foreach (string droppedFilePath in Jobs)
{
if (System.IO.Path.GetExtension(droppedFilePath) == ".mp3" ||
System.IO.Path.GetExtension(droppedFilePath) == ".wav" ||
System.IO.Path.GetExtension(droppedFilePath) == ".flac")
{
double pct = count / total;
// Report this file
bgWorker.ReportProgress((int) (pct * 100), droppedFilePath);
var provider = (XmlDataProvider)this.Resources["CUEData"];
XmlDocument xmlcuelijst = provider.Document;
XmlNode cueshow = xmlcuelijst.SelectSingleNode("CUEShow");
XmlNode maincues = cueshow.SelectSingleNode("Maincues");
XmlElement Maincue = xmlcuelijst.CreateElement("Maincue");
XmlElement nr = xmlcuelijst.CreateElement("nr");
XmlElement Description = xmlcuelijst.CreateElement("Description");
XmlElement Cuetype = xmlcuelijst.CreateElement("Cuetype");
XmlElement Name = xmlcuelijst.CreateElement("Name");
XmlElement Path = xmlcuelijst.CreateElement("Path");
XmlElement Duration = xmlcuelijst.CreateElement("Duration");
XmlElement Type = xmlcuelijst.CreateElement("Type");
XmlElement Fade = xmlcuelijst.CreateElement("Fade");
XmlElement Fadein = xmlcuelijst.CreateElement("Fadein");
XmlElement Fadeout = xmlcuelijst.CreateElement("Fadeout");
XmlElement Delay = xmlcuelijst.CreateElement("Delay");
XmlElement Delaytime = xmlcuelijst.CreateElement("Delaytime");
XmlElement Loop = xmlcuelijst.CreateElement("Loop");
XmlElement FX = xmlcuelijst.CreateElement("FX");
XmlElement Filename = xmlcuelijst.CreateElement("Filename");
Maincue.AppendChild(nr);
Maincue.AppendChild(Cuetype);
Maincue.AppendChild(Name);
Maincue.AppendChild(Path);
Maincue.AppendChild(Description);
Maincue.AppendChild(Duration);
Maincue.AppendChild(Type);
Maincue.AppendChild(Fade);
Maincue.AppendChild(Fadein);
Maincue.AppendChild(Fadeout);
Maincue.AppendChild(Delay);
Maincue.AppendChild(Delaytime);
Maincue.AppendChild(Loop);
Maincue.AppendChild(FX);
count += 1;
}
}
}
void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Addingcues.Visibility = Visibility.Hidden;
}
这有效(将数组更改为列表)但在Appendchild操作中,代码突然停止运行,我在第一个和第二个Appendchild行设置了两个断点,第一个被触发,但第二个不是......
答案 0 :(得分:1)
不使用在异步线程上启动Action并继续处理的BeginInvoke,而是使用Invoke调用,该调用在同一个线程上同步执行(即在继续之前等待完成处理)。
Jon Skeet比我更好地解释in this post。
答案 1 :(得分:1)
很难准确说明是什么让这段代码需要Invoke / BeginInvoke - 看起来Dropaudio方法只是一个事件处理程序(在GUI线程上)。
也许最简单的方法是使用BackgroundWorker,它可以使简单的多线程更容易。
class MyClass
{
BackgroundWorker bgWorker = new BackgroundWorker();
public MyClass()
{
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.ProgressChanged +=
new ProgressChangedEventHandler(bgWorker_ProgressChanged);
bgWorker.WorkerReportsProgress = true;
this.Drop += new DragEventHandler(Dropaudio);
}
private void Dropaudio(object sender, System.Windows.DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
List<string> Jobs = new List<string>(droppedFilePaths);
bgWorker.RunWorkerAsync(Jobs);
}
}
void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.ProgressPercentage == 0)
{
Addingcues.Visibility = Visibility.Visible;
}
addcuepath.Text = e.UserState.ToString;
}
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
string[] Jobs = e.Argument as string[];
bgWorker.ReportProgress(0, "Processing Data");
double count = 0;
double total = Jobs.Count;
foreach (string droppedFilePath in Jobs)
{
if (System.IO.Path.GetExtension(droppedFilePath) == ".mp3" ||
System.IO.Path.GetExtension(droppedFilePath) == ".wav" ||
System.IO.Path.GetExtension(droppedFilePath) == ".flac")
{
double pct = count / total;
// Report this file
bgWorker.ReportProgress((int) (pct * 100), droppedFilePath);
var provider = (XmlDataProvider)this.Resources["CUEData"];
XmlDocument xmlcuelijst = provider.Document;
// Do other stuff from above
count += 1;
}
}
}
void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Addingcues.Visibility = Visibility.Hidden;
}
}
请注意,使用ProgressChanged事件时可以轻松添加ProgressBar。我假设“Addingcues”是您希望在处理期间可见的控件,“addcuePath”是您希望随进度更新的文本框(TextBlock?)。