为啥我工作时状态栏没有更新?

Posted

技术标签:

【中文标题】为啥我工作时状态栏没有更新?【英文标题】:Why isn't my StatusBar updating while I do work?为什么我工作时状态栏没有更新? 【发布时间】:2011-12-14 22:18:02 【问题描述】:

我想在我的应用程序中添加一个状态栏,但我不知道最好的解决方案是什么?我正在将 c# 与 WPF 和模型 MVVM 一起使用。

现在我有一个部分可行的解决方案。问题是状态栏没有像我希望的那样经常更新。 例如,当我将一个新值写入状态栏绑定的字符串时,状态栏将更新得太晚,并希望显示任何差异。

一个简单的例子(不是真实的代码):

StatusBar 绑定到状态并且初始 = 就绪。

    状态 = 正在下载

    下载方式

    状态 = 就绪

这不会导致视觉上的变化。当我调试代码时,状态的值会更新,但不会在状态栏中更改。

你有什么建议吗?

我的代码

XAML 视图:MainView.xaml

<StatusBar DockPanel.Dock="Bottom" >
        <StatusBar.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid Margin="0 -5 0 0">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="4*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </StatusBar.ItemsPanel>

        <StatusBarItem Grid.Column="0">
            <TextBlock Name="statusBarStatus" Text="Binding Status"></TextBlock>
        </StatusBarItem>
    </StatusBar>

MainViewModel 的一部分

private void UpdateDepartmentsExecute()
    
        Status = "Updating...";

        repository.ShowAppDep = ShowAppDep;
        repository.ShowInDep = ShowInDep;
        repository.ShowSisDep = ShowSisDep;

        repository.getPriority1 = SetPriorityTo1;
        repository.getPriority2 = SetPriorityTo2;
        repository.getPriority3 = SetPriorityTo3;
        repository.getPriority4 = SetPriorityTo4;
        repository.getPriority5 = SetPriorityTo5;

        repository.UpdateTasksToShow();
        repository.UpdateWorkareas();
        repository.UpdateEmployees();
        repository.UpdateTasksToShowByEmployee();
        repository.UpdateWorkAreaByEmployee();
        repository.GenerateStatistics();

        TasksToShowCount = repository.TasksToShow.Count();

        if (SelectedView == new Uri("pack://application:,,,/View/EstimateLoadView.xaml"))
        
            MessageBox.Show("The Gantt Chart wan't show all relations when you are filtering the data. This might be a source to errors.", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
            SelectedView = new Uri("pack://application:,,,/View/EntryView.xaml");
        

        Status = "Ready";        

【问题讨论】:

你能把你的视图和视图模型代码贴出来 我同意 devdigital。请发布课程或至少发布您绑定的属性。我已经使用了带有 MVVM 和转换器的状态栏,并且从未遇到任何问题。我假设您的 INotifyPropertyChanged 可能无效,或者您的应用程序太忙以至于 UI 线程无法赶上刷新可能由线程操作导致的 UI。 谁需要代码?他在 UI 线程上做所有事情,在他完成之前阻止对栏的更新。 那么如果我实现多线程它会工作吗? 【参考方案1】:

您必须在后台线程中进行下载,最简单的方法是使用 BackgroundWorker 组件。否则,您的下载将发生在 UI 线程中,这意味着您的阻塞消息正在泵送和重新绘制。阻止这意味着您的 UI 不会更新,更糟糕的是可能意味着 Windows 认为您的应用程序没有响应。

要更新绑定到 UI 线程的集合,您应该能够使用 ReportProgress 事件并传递一些数据,然后处理程序可以使用这些数据来更新 OC。 ReportProgress 处理程序将被编组到适当的 UI 线程。

【讨论】:

好吧...到此为止。唯一的问题是下载方法在我绑定到 UI 的 ObervalCollection 中进行编辑。所以它想让我做改变。你有什么建议吗?【参考方案2】:

使用后台线程中的调度程序(假设您正在同时运行状态更新!)。这是一篇不错的博文:Updating UI from a background thread

【讨论】:

我想这样做,但我现在没有。在您发给我的示例中,我不知道如何执行此部分:runner.RequestFinished。我找不到任何名为 RequestFinished 的想法? 还有一件事。如何从后面的代码中调用 ModelView 提供的方法?如果我想创建一个后台线程,这个接缝非常重要,因为我只能从后面的代码调用开始调用。还是我错了? 该示例使用事件处理程序方法(它订阅名为 RequestFinished 的事件),但在您的情况下,您可以从其他方法进行 BeginInvoke 调用。例如,您用于更新状态的方法(再次假设您在后台线程中运行它!)【参考方案3】:

您不能绑定到Properties.Settings.Default。因此,如果您希望 DataBinding 工作,您应该绑定到实现 INotifyPropertyChanged 的类的属性,在您的情况下。

在同一个链接页面上,您还应该看到一个示例,说明如何执行此操作。

像 Lauri 建议的那样,还要添加非 UI 阻塞调用,以便让您的 UI 有“呼吸”的可能性。

【讨论】:

现在我已经在我的存储库private string status = "Loading..."; public string Status get return status; set status = value; Notify("Status"); 中添加了一个新变量,并将视图中的绑定编辑到这个&lt;StatusBarItem Grid.Column="0"&gt; &lt;TextBlock Name="statusBarStatus" Text="Binding Status"&gt;&lt;/TextBlock&gt; &lt;/StatusBarItem&gt; 中,并且我的视图模型已经得到了这个变量,每当我想要更改状态消息。 public string Status get return repository.Status; set repository.Status = value; 应用启动时获取值,但没有获取任何更新??? 刚刚将通知移动到我的 ViewModel 中,现在它又可以部分工作了。它正在获取状态消息的更改,但只是其中的最后一个。不是代码开头的那个。 您只看到“就绪”,所以最终结果,只是因为您在“长时间运行的操作”中阻止了 UI。在其他线程上运行该操作,您将看到您希望出现在状态栏上的文本。显然,您需要使用主 UI 线程调整不同线程的工作。

以上是关于为啥我工作时状态栏没有更新?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的状态栏上的图标不能在不同的模式下改变?

单击时导航栏未更新为活动状态

为啥我在启动我的应用程序时会看到双状态栏?

为啥我的应用在不录制时会显示正在录制(闪烁的红色)状态栏?

为啥 iPhone GPS 箭头出现在状态栏中,即使我没有在位置管理器上调用 startUpdatingLocation?

Nib 文件在加载时忽略状态栏。为啥?