如何在 Binding 中加载控件而不阻塞 UI?

2024-01-06

我有这种情况:

我想在主窗口的 ViewModel 中加载一个集合,我有一个大数据,所以当我进入人员集合的幻灯片时,它应该等待完成加载,然后我可以看到完整的列表,我有以下内容:

  • 在 xaml 代码中我有:

    <ListView ..... 
    ItemsSource{Binding PeopleList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
    ... />
    
  • 在视图模式下我有:

    // ...
    private ObservableCollection<Person> _People;
    public ObservableCollection<Person> People
    { get{return _People;} set{ _People = value; RaisePropertyChange("People");}}
    // ...
    

我想在加载第一个完全开始加载第二个之后一一加载所有人员列表......等等而不阻塞主窗口我希望我的窗口看起来像:

我厌倦了自己做,但我失败了。谢谢之前。


有一些方法可以使用 SynchronizationContext 从另一个线程修改视图。

请看这个例子:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var sync = SynchronizationContext.Current;
            BackgroundWorker w = new BackgroundWorker();
            w.DoWork+=(_, __)=>
                {
                    //sync.Post(p => { button.Content = "Working"; }, null);
                    int j = 0;
                    for (int i = 0; i < 10; i++)
                    {
                        j++;
                        sync.Post(p => { button.Content = j.ToString(); }, null);
                        Thread.Sleep(1000);
                    }
                    sync.Post(p => { button.Background = Brushes.Aqua; button.Content = "Some Content"; }, null);
                };
            w.RunWorkerAsync();
        }

这就是视图:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button x:Name="button" Content="Some Content" Click="Button_Click"/>
    </Grid>
</Window>

此代码多次更新视图(在本例中为按钮)。我认为这解决了你最初的问题。

- - 编辑 - -

这是使用这个想法的更好方法:我建议在基本视图模型中创建这样的方法:

    public void LockAndDoInBackground(Action action, string text, Action beforeVisualAction = null, Action afterVisualAction = null)
    {
        if (IsBusy)
            return;
        var currentSyncContext = SynchronizationContext.Current;
        ActiveThread = new Thread((_) =>
        {                
            currentSyncContext.Send(t =>
            {
                IsBusy = true;
                BusyText = string.IsNullOrEmpty(text) ? "Wait please..." : text;
                if (beforeVisualAction != null)
                    beforeVisualAction();
            }, null);
            action();
            currentSyncContext.Send(t =>
            {
                IsBusy = false;
                BusyText = "";
                if (afterVisualAction != null)
                    afterVisualAction();
            }, null);
        });
        ActiveThread.Start();
    }

这样任何子视图模型都可以使用它来执行大量数据处理,并且 UI 不会被冻结。IsBusy and BusyText是绑定到视图等待消息和等待元素的可见性的视图模型变量。 这是在子视图模型命令中使用的示例:

  private RelayCommand _SomeCommand;
  public RelayCommand SomeCommand
    {
        get { return _SomeCommand ?? (_SomeCommand = new RelayCommand(ExecuteSomeCommand, CanExecuteSomeCommand)); }
    }

    private void ExecuteSomeCommand()
    {
        Action t = ()=> 
        {
            //some action
        };

        LockAndDoInBackground(t, "Generating Information...");
    }

    private bool CanExecuteSomeCommand()
    {
        return SelectedItem != null;
    }

希望这将成为一个更清晰的例子。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Binding 中加载控件而不阻塞 UI? 的相关文章

  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • 在开关中使用“goto”?

    我看到了一个建议的编码标准 内容如下Never use goto unless in a switch statement fall through 我不跟 这个 例外 案例到底是什么样的 这证明了goto 此构造在 C 中是非法的 swi
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 在 omp 并行 for 循环中使用 unique_ptr 会导致 SEG.FAULT

    采取以下代码 include
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 多线程——更快的方法?

    我有一堂有吸气剂的课程getInt 和一个二传手setInt 在某个领域 比如说领域 Integer Int 一个类的一个对象 比如说SomeClass The setInt 这里是同步的 getInt isn t 我正在更新的值Int来自
  • 增强精神、递归和堆栈溢出

    为什么下面的代码在运行时崩溃 它会给出堆栈溢出错误 include
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • 英文日期差异

    接近重复 如何计算相对时间 https stackoverflow com questions 11 how do i calculate relative time 如何在 C 中计算某人的年龄 https stackoverflow c
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • 使用 using 声明时,非限定名称查找如何工作?

    根据 C 标准 这是格式错误还是格式良好 namespace M struct i namespace N static int i 1 using M i using N i int main sizeof i Clang 拒绝它 GCC
  • INotifyPropertyChanged 和 propertyName

    我一直不确定它的含义propertyName实施时INotifyPropertyChanged 所以一般来说你实现INotifyPropertyChanged as public class Data INotifyPropertyChan

随机推荐