【问题标题】:wpf drag drop show processing popupwpf拖放显示处理弹出窗口
【发布时间】:2010-08-15 22:50:22
【问题描述】:

我用 wpf c# 编写了一个程序。 我制作了一个拖放处理程序,它将一些项目添加到列表框中。虽然程序正在执行此操作(这需要一些时间),但我希望 Grid 将其属性可见性更改为可见,并且我想更新一个文本框以向用户显示正在处理的文件。代码如下:

更新:解决方案实施尝试

            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 行设置了两个断点,第一个被触发,但第二个不是...

【问题讨论】:

    标签: c# wpf


    【解决方案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?)。

    【讨论】:

      【解决方案2】:

      不要执行 BeginInvoke,它会在异步线程上启动 Action 并继续处理,而是使用 Invoke 调用,它会在同一线程上同步执行(即在继续之前等待完成处理)。

      Jon Skeet 比我解释得更好 in this post

      【讨论】:

      • 看看上面的代码 - Dropaudio 方法只是事件处理程序吗?如果是这样,是什么让这个多线程?
      • 这只是事件处理程序,我在上面尝试了您的解决方案,但我不希望它在单独的类中。现在我只是声明了一个新的后台工作人员并将您的代码应用到 drop 事件处理程序中,网格出现了,但是什么也没发生
      • 上面的例子不是一个单独的类 - 我只是在你的类中展示它(我只是称之为 MyClass,因为我不知道你的实际类的名称),你需要声明一个 BackgroundWorker,并在构造函数中连接事件。你添加事件了吗?如果是这样,您确实将“// Do other stuff from above”的注释行替换为其余的 XML 处理代码,对吧?
      • 嗨,是的,我现在已经正确设置了代码,但奇怪的是,在 xml 处理的某个地方,代码突然停止执行。我设置了两个断点,第一个到达但第二个没有...
      • 您是否有任何类型的异常处理,无论是围绕此代码还是全局 UnhandledException 处理程序?如果是这样,请检查那里;如果没有,并且您需要更多帮助,最好提出一个新问题以基于该问题启动一个线程。
      猜你喜欢
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 2022-12-14
      • 2021-01-11
      • 1970-01-01
      • 2012-07-15
      相关资源
      最近更新 更多