如何确保 ViewModel 属性在再次更改其值之前已绑定在视图上?

2024-05-10

有以下情况:ViewModel有一个变化非常快的对象。 (通过不同的线程)

View通过以下方式获悉NotifyPropertyChanged界面,但似乎它的工作速度很慢,并且在视图绑定新值并绘制它之前,它会更改更多次,因此它会丢失一些值。

我也尝试过绑定View然后排队ViewModel could Enqueue it and View可以通过出队进行绘制。

不幸的是又出现了一个问题:之后RaisePropertyChanged(() => queue); View没有被告知它已被更改。

在这种情况下,实施INotifyPropertyChanged界面不起作用。

你有什么主意吗?

的示例代码ViewModel:

public class ExamplaryViewModel
{
    public ExamplaryViewModel()
    {
        Messenger.Default.Register<NotificationMessage<Message>>(this, m => ProcessNotificationMessage(m.Content));
    }    

    public void ProcessNotificationMessage(Message message)
    {   
        MessageOftenBeingChanged = message;
        RaisePropertyChanged(() => MessageOftenBeingChanged );
    }
}

View绑定到MessageOftenBeingChanged.

另一种选择是按照评论中的建议准备快照:

public void ProcessNotificationMessage(Message message)
{
    Messages.Enqueue(message);
    RaisePropertyChanged(() => Messages);
}

View:

<controls:RichTextBoxMonitor Messages="{Binding Messages} 

Control:

public class BindableRichTextBox : RichTextBox
{

    public static readonly DependencyProperty MessagesProperty = DependencyProperty.Register("Messages",
     typeof(ConcurrentQueue<Message>), typeof(BindableRichTextBox ), new FrameworkPropertyMetadata(null, OnQueueChangedChanged));


    public ConcurrentQueue<Message> CyclicMessages
    {
        get { return (ConcurrentQueue<Message>)GetValue(MessagesProperty ); }

        set { SetValue(MessagesProperty , value); }

但不幸的是RaisePropertyChanged()方法不会触发发生的更改。

我计划控制事件OnQueueChangedChanged尝试出列并将项目绘制为段落的新内联。


你可以实施生产者-消费者 http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem.

看看这个简化版本。

  • RunProducer仅用于测试,就您而言ProcessNotificationMessage将以类似的方式工作。
  • RunConsumer是一种不断检查新消息和设置的方法Message有一些延迟,否则用户将无法读取它。
  • 这只是概念的快速证明,但您可以更好地实现它,例如通过提供方法ShowNextMessage and IsMessageAvailable,然后视图可以决定何时准备好显示新消息并请求它。这将是一个更好的设计。即使用户可以更快地隐藏一些消息,您只需要绑定ShowNextMessage to Click event.
  • 完整源代码 https://dl.dropboxusercontent.com/u/105509493/udostepnione/Messages.zip

    public class MyViewModel : INotifyPropertyChanged
    {
        public ConcurrentQueue<string> Queue { get; set; }
    
        #region Message
    
        private string _message;
    
        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                if (_message != value)
                {
                    _message = value;
                    OnPropertyChanged();
                }
            }
        }
        #endregion
    
        public MyViewModel()
        {
            Queue = new ConcurrentQueue<string>();
            RunProducer();
            RunConsumer();
        }
    
        public void RunProducer()
        {
            Task.Run(() =>
            {
                int i = 0;
                while (true)
                {
                    if (Queue.Count < 10)
                        Queue.Enqueue("TestTest " + (i++).ToString());
                    else
                        Task.Delay(500).Wait();
                }
            });
        }
    
        public void RunConsumer()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    if (Queue.Count > 0)
                    {
                        string msg = "";
                        if (Queue.TryDequeue(out msg))
                            Message = msg;
                    }
                    else
                    {
                        Task.Delay(500).Wait();
                    }
    
                    Task.Delay(100).Wait();
                }
            });
        }
    
        #region INotifyPropertyChanged
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void OnPropertyChanged([CallerMemberName]string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        #endregion
    }
    

如果队列为空,您可以使用ManualResetMonitor以避免不必要的迭代。

对您的代码的备注:
如果可以更改集合,那么出于绑定目的,您应该仅使用ObservableCollection<T>(或者实现的东西INotifyCollectionChanged),因为它跟踪更改并且不会重新加载所有内容。

然而,在您的代码中,应该刷新整个绑定(因为您通知整个集合已更改),但我认为这种机制更智能,它会检查引用是否相等,如果相等则不会发生刷新。将其设置为可能是一个恶作剧null然后回来会刷新它:-)。

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

如何确保 ViewModel 属性在再次更改其值之前已绑定在视图上? 的相关文章

  • C++ 长 switch 语句还是用地图查找?

    在我的 C 应用程序中 我有一些值充当代表其他值的代码 为了翻译代码 我一直在争论使用 switch 语句还是 stl 映射 开关看起来像这样 int code int value switch code case 1 value 10 b
  • 如何在 XAML/WPF 中存储和检索多个形状?

    使用 XAML WPF 做一些简单的事情似乎遇到了很多问题 我已经使用矩形和椭圆形等形状创建了一些基于 XAML 的图像来创建我需要应用程序的其他部分使用的图标 但我不能似乎找到了如何做到这一点 我似乎能够在资源字典中存储画布 但无法在任何
  • 将完整模板参数值映射到原始类型

    我想将数字映射到类型 在这个例子中 我将创建一个函数 将 sizeof 结果映射到有符号的原始类型 我想知道是否有更好的方法来完成我在现代 C 中所做的事情 即采用模板化值并将其转换为类型 现在 这可以将大小转换为已知类型 但我似乎无法在标
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • WindowsFormsHost ZOrder

    看起来 WindowsFormsHost 控件被设置为显示在顶部 有没有办法更改其 z 顺序 以允许同一窗口上的其他 WPF 控件在 WindowsFormsHost 控件之上可见 不幸的是 不能 由于 winformshost 合成到 W
  • 一元 +/- 运算符如何可能导致“-a”或“+a”中的整数提升,“a”是算术数据类型常量/变量?

    这句看似微不足道的台词摘自我的迈克 巴纳汉和布雷迪的 C 书 第 2 8 8 2 节 http publications gbdirect co uk c book chapter2 expressions and arithmetic h
  • C# 开源 NMEA 解析器 [已关闭]

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

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • 逆向工程 ASP.NET Web 应用程序

    我有一个 ASP NET Web 应用程序 我没有源代码 该 bin 包含 10 个程序集和一个 compiled 文件 我在 App Code dll 上使用 Reflector 它向我显示了类和命名空间之类的东西 但它太混乱了 有没有什
  • 需要提取字符串中点后的最后一个数字,如“7.8.9.1.5.1.100”

    我需要提取 C 字符串中最后一个点后面的最后一个数字 例如 7 8 9 1 5 1 100 并将其存储在整数中 Added 该字符串也可以是 7 8 9 1 5 1 1 或 7 8 9 1 5 1 0 我还想验证它在最后一个点之前恰好是 7
  • LINQ 中的“from..where”或“FirstOrDefault”

    传统上 当我尝试从数据库中获取用户的数据时 我使用了以下方法 在某种程度上 DbUsers curUser context DbUsers FirstOrDefault x gt x u LoginName id string name c
  • INotifyPropertyChanged 和 propertyName

    我一直不确定它的含义propertyName实施时INotifyPropertyChanged 所以一般来说你实现INotifyPropertyChanged as public class Data INotifyPropertyChan
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne

随机推荐

  • 小数除以小数并得到零

    为什么当我这样做时 select CAST 1 AS DECIMAL 38 28 CAST 1625625 AS DECIMAL 38 28 我得到 0 吗 但是当我得到 0 时 select CAST 1 AS DECIMAL 20 10
  • 对每个元素使用条件的 Numpy 过滤器

    我有一个过滤器表达式如下 feasible agents filter lambda agent agent gt cost task agent agents where agents是一个Python列表 现在 为了提高速度 我尝试使用
  • 如何解析 FeignClient 响应 json 中的蛇形字段?

    我在 Spring Boot Web 应用程序中配置了一个 FeignClient 我在其中调用返回以下对象的外部 api public class Issue private Assignee assignee private Date
  • 如何转置 R markdown 文档中的表格?

    假设我打印一个名为summary table的数据框 如下所示 summary table data frame a c 1 2 3 b c 11 12 13 c c 21 22 23 d c 31 32 33 e c 41 42 43 f
  • 我很难理解 OPTICS 聚类算法中排序的概念

    我很难理解 OPTICS 聚类算法中排序的概念 如果有人对顺序给出逻辑和直观的解释 并解释什么 我将不胜感激res order下面的代码做了什么以及什么是可靠性图 可以通过命令 plot res 获得 library dbscan set
  • 使用 pyobjc 将元数据写入 pdf

    我正在尝试使用以下 python 代码将元数据写入 pdf 文件 from Foundation import from Quartz import url NSURL fileURLWithPath test pdf pdfdoc PDF
  • 不要在最近的应用程序中显示我的应用程序

    我希望当用户在 hdevice 中运行或关闭我的应用程序时 不要在最近的应用程序中显示我的应用程序 我的目的是 用户禁止运行我的应用程序 我很抱歉说得不好 尝试这个 为您的每一个activity android excludeFromRec
  • SwiftUI TabbedView 仅显示第一个选项卡的内容

    我正在尝试建立一个TabbedView使用以下简单代码 TabbedView Text Hello world tabItemLabel Text Hello Text Foo bar tabItemLabel Text Foo 运行时 两
  • 删除最初使用“未知分词器”创建的表?

    我有一个 sqlite3 数据库 错误消息显示 无法删除此数据库中的单个表unknown tokenizer mm 我直接用命令试了一下DROP TABLE tablename 里面最新的SQLiteSpy http www yunqa d
  • 在 QtCreator 中将 OpenCV 2.3 与 Qt 结合使用

    随着 OpenCV 2 3 版本终于发布 我想在我的系统上编译并安装这个最新版本 由于我经常使用 Qt 和 QtCreator 我当然希望能够在我的 Qt 项目中使用它 我已经尝试了几种方法几个小时 但总是出现错误 第一次尝试 使用WITH
  • perf 找不到外部模块符号

    跑步时perf它找到了我的程序的内核符号和符号 但没有找到外部模块符号 我已经编写了一个内核模块 我使用它加载insmod我怎么知道perf也找到它的符号 我正在运行 2 6 37 6 内核 无法升级 我的perf尚不支持矮人选项 但我认为
  • 让 Emacs ansiterm 和 Zsh 更好地发挥作用

    我一直在尝试在 emacs 会话中使用 Zsh 而无需 emacs 重新映射所有 Zsh 键 我发现 ansi term 对此非常有效 但是我仍然遇到一些问题 我输出了很多垃圾字符 我可以用以下方法修复它 Setup proper term
  • 如何在 Python 中获取显示器分辨率?

    获得显示器分辨率的最简单方法是什么 最好是在元组中 我创建了一个PyPI模块 https pypi org project screeninfo 为此原因 pip install screeninfo 代码 from screeninfo
  • Javascript 中的 k 均值聚类实现? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要 k means 聚类算法的 Javascript 实现 我只有一维数据 很少超过 100 个项目
  • 检查Web服务是否存在

    有人可以告诉我确定给定 URL 是否存在 Web 服务 ASP NET 的最佳方法吗 我假设一种方法类似于使用 System Net Webclient 发出请求 但我如何确定它是否是有效的 Web 服务以及我应该发出哪种类型的请求 编辑
  • Visual Studio 2008 (C#) 与 SQL Compact Edition 数据库错误:26

    与网络相关或特定于实例的 建立时发生错误 连接到 SQL Server 服务器 未找到或无法访问 验证实例名称是否为 正确并且 SQL Server 是 配置为允许远程 连接 提供商 SQL 网络 接口 错误 26 错误定位 指定服务器 实
  • 从 Symfony2 中的服务重定向

    我有一项查找页面数据的服务 但如果找不到该数据 则应重定向到主页 对于我的一生 我不知道如何在 Sf2 中做到这一点 有很多不同的方法可以使用服务和路由器 但似乎都不起作用 namespace Acme SomeBundle Service
  • Rfc2898DeriveBytes 与密码的 Sha2 哈希生成

    我最近知道使用 SHA256 为加盐密码生成密码哈希 在阅读了一些有关加盐密码和安全性的内容后 我看到rfc2898derivebytes and passwordderivebytes NET 中的类 使用有什么好处吗rfc2898der
  • Rails_admin 中的范围作为过滤器

    我在我的应用程序中使用rails admin 我的模型上有一些范围 以下是一个示例 class User lt ActiveRecord Base scope unconfirmed where confirmed at IS NULL e
  • 如何确保 ViewModel 属性在再次更改其值之前已绑定在视图上?

    有以下情况 ViewModel有一个变化非常快的对象 通过不同的线程 View通过以下方式获悉NotifyPropertyChanged界面 但似乎它的工作速度很慢 并且在视图绑定新值并绘制它之前 它会更改更多次 因此它会丢失一些值 我也尝