UWP:通过后台线程中的数据绑定更新UI [英] UWP: Updating UI through data binding from a background thread

查看:456
本文介绍了UWP:通过后台线程中的数据绑定更新UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在UWP应用程序中使用x:Bind(编译绑定)将TextBlock绑定到ViewModel中的整数属性,该属性由值转换器转换为字符串.我在工作线程上的ViewModel中使用一种方法来设置属性并调用PropertyChanged事件.但是,我遇到了一个异常(特别是在MainPage.g.cs文件的XamlBindingSetters类中),说:该应用程序调用了被编组到另一个线程的接口." 根据这篇文章,在WPF中应该可以正常工作;是在WinRT/UWP中删除了这种易用的功能,还是我做错了什么?

I'm using x:Bind (compiled binding) in my UWP app to bind a TextBlock to an integer property in the ViewModel which is converted to a string by a value converter. I am using a method in the ViewModel on the worker thread to set the properties and call the PropertyChanged event. However, I am getting an exception (specifically, it's in the XamlBindingSetters class in the MainPage.g.cs file) saying, "The application called an interface that was marshalled for a different thread." According to this post, this should work just fine in WPF; has this ease of functionality been removed in WinRT/UWP or am I doing something wrong?

这正是我在做什么.

我的财产是这样定义的:

My property is defined like this:

private int myProperty;

    public int MyProperty
    {
        get { return myProperty; }
        set
        {
            Set(ref myProperty, value);
        }
    }

Set方法是Template 10库的一部分,并且已定义:

The Set method is part of the Template 10 library and is defined:

public bool Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null) 
     { 
         if (object.Equals(storage, value)) 
             return false; 
         storage = value; 
         RaisePropertyChanged(propertyName); 
         return true; 
     } 

从我所看到的那里没什么错;只需确保新值与旧值不同,然后调用RaisePropertyChanged(propertyName)即可确保应用程序实际上正在运行(不在设计模式下),然后引发PropertyChanged事件.

Nothing wrong there from what I can see; it just makes sure the new value is different than the old value and then calls RaisePropertyChanged(propertyName) which makes sure the app is actually running (not in design mode) and then raises the PropertyChanged event.

我通过工作线程设置属性:

I set my property from a worker thread:

MyProperty = newValue;

以及到达XamlBindingSetters类的时间:

and when it gets to the XamlBindingSetters class:

internal class XamlBindingSetters
    {
        public static void Set_Windows_UI_Xaml_Controls_TextBlock_Text(global::Windows.UI.Xaml.Controls.TextBlock obj, global::System.String value, string targetNullValue)
        {
            if (value == null && targetNullValue != null)
            {
                value = targetNullValue;
            }
            obj.Text = value ?? global::System.String.Empty;
        }
    };

它在最后一行中断(obj.Text = ...),并告诉我该应用程序调用了为另一个线程编组的接口.我在做什么错了?

it breaks on that last line (obj.Text = ...) and tells me that the application called an interface that was marshalled for a different thread. What am I doing wrong?

推荐答案

您需要执行UI线程中的所有图形对象.

You need to execute all graphical objects in the UI Thread.

  • 第一个解决方案,使用 MVVM Light 框架.

请参见 DispatcherHelper的简单示例

第二个解决方案,使用 ISynchronizeInvoke .

Second solution, using ISynchronizeInvoke.

典型用法:

obj.Invoke((MethodInvoker) SomeMethod);

请参见如何使用ISynchronizeInvoke接口?

这篇关于UWP:通过后台线程中的数据绑定更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆