C# WPF进度条未显示

C# WPF进度条未显示,c#,wpf,observablecollection,C#,Wpf,Observablecollection,我将WPFProgressBar的不确定性设置为True,可见性设置为Hidden。在事件处理程序中,我试图使ProgressBar在更新ObservableCollection时可见(以及其ItemsSource为ObservableCollection的ListView)。我希望System.Windows.Forms.Application中的DoEvents()可以使它可见,但它不可见。 我注意到SetPBarHelper(()=>{..})通常比ListView显示的可视更改要早很多

我将WPF
ProgressBar
的不确定性设置为True,可见性设置为Hidden。在事件处理程序中,我试图使ProgressBar在更新
ObservableCollection
时可见(以及其ItemsSource为
ObservableCollection
的ListView)。我希望
System.Windows.Forms.Application
中的
DoEvents(
)可以使它可见,但它不可见。 我注意到
SetPBarHelper(()=>{..})
通常比ListView显示的可视更改要早很多

如何使
ProgressBar
在事件处理程序代码中可见

如何判断即使
ObserableCollection
已完成添加项,my
ListView
是否仍在更新

<ProgressBar x:Name="GeneralProgressBar" Width="300" Height="15" IsIndeterminate="True" Visibility="Hidden"/>

private void SetPBar(bool isVisible)
{
    if (isVisible)
        GeneralProgressBar.Visibility = System.Windows.Visibility.Visible;
    else
        GeneralProgressBar.Visibility = System.Windows.Visibility.Hidden;
}

private void SetPBarHelper(Action handler)
{
    SetPBar(true);                // try to make ProgressBar visible
    System.Windows.Forms.Application.DoEvents();
    handler();                    // use the event handling, which run database query
    SetPBar(false);               // try to make ProgressBar disappear
}


private void CommandForumImagesBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    SetPBarHelper(() =>
    {
        if (e.Parameter == null)
            return;
        var vm = e.Parameter as ForumViewModel;
        if (vm != null)
        {

        }
    });
}

public sealed class ImageGroupCollection : ObservableCollection<ImageGroup>
{
    public ImageGroupCollection() : base() { }

    public void Update(DateTime start, DateTime end)
    {
        ClearItems();
        var list = MyDatabase.GetRecords(start, end);
        if (list != null)
        {
            foreach (var g in list)
            {
                Add(g);
            }
        }
    }
}

私有void SetPBar(bool可见)
{
如果(可见)
GeneralProgressBar.Visibility=System.Windows.Visibility.Visible;
其他的
GeneralProgressBar.Visibility=System.Windows.Visibility.Hidden;
}
私有void SetPBarHelper(操作处理程序)
{
SetPBar(true);//尝试使ProgressBar可见
System.Windows.Forms.Application.DoEvents();
handler();//使用运行数据库查询的事件处理
SetPBar(false);//尝试使ProgressBar消失
}
已执行UMImagesBinding_的私有无效命令(对象发送器,已执行路由EventTarget e)
{
SetPBarHelper(()=>
{
如果(e.Parameter==null)
返回;
var vm=e.参数为ForumViewModel;
if(vm!=null)
{
}
});
}
公共密封类ImageGroupCollection:ObservableCollection
{
公共ImageGroupCollection():base(){}
公共无效更新(日期时间开始,日期时间结束)
{
ClearItems();
var list=MyDatabase.GetRecords(开始、结束);
如果(列表!=null)
{
foreach(列表中的变量g)
{
添加(g);
}
}
}
}

您的问题仅仅是因为您阻塞了UI线程。你不能那样做

当UI线程再次运行消息循环时,您已经设置了
ProgressBar.Visible=false
。从不绘制
ProgressBar

假设您使用的是.NET4.5,则需要按如下方式重写代码

private async Task SetPBarHelper(Action handler)
{
    SetPBar(true);                // try to make ProgressBar visible
    System.Windows.Forms.Application.DoEvents();
    await Task.Run(handler);                    // use the event handling, which run database query
    SetPBar(false);               // try to make ProgressBar disappear
}

但总的来说,您需要尽快将UI线程的控制权返回到应用程序循环,以允许它重新绘制窗口,并在WorkerThread上运行更新。

为什么要使用System.windows.Forms.application.DoEvents()?这不是WinForm的东西吗?你看过BackgroundWorker了吗?如果将handler()放在BackgroundWorker中,它应该让您在查询运行时看到进度条