UWP:通过后台线程的数据绑定更新 UI
UWP: Updating UI through data binding from a background thread
我在我的 UWP 应用程序中使用 x:Bind(编译绑定)将 TextBlock 绑定到 ViewModel 中的整数 属性,该整数由值转换器转换为字符串。我在工作线程的 ViewModel 中使用一个方法来设置属性并调用 PropertyChanged 事件。但是,我得到一个异常(具体来说,它在 MainPage.g.cs 文件的 XamlBindingSetters class 中)说 "The application called an interface that was marshalled for a different thread." According to this post,这在 WPF 中应该工作得很好; WinRT/UWP 中是否删除了这种易用性功能,还是我做错了什么?
这正是我正在做的。
我的属性是这样定义的:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set
{
Set(ref myProperty, value);
}
}
Set 方法是模板 10 库的一部分,定义如下:
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(属性Name) 以确保应用程序实际上是 运行(不处于设计模式),然后引发 PropertyChanged 事件。
我从工作线程设置 属性:
MyProperty = newValue;
当它到达 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 = ...) 并告诉我应用程序调用了一个为不同线程编组的接口。我做错了什么?
您需要在 UI 线程中执行所有图形对象。
第一个解决方案,使用MVVM Light框架。
见Simple example of DispatcherHelper
第二种方案,使用ISynchronizeInvoke.
典型用法:
obj.Invoke((MethodInvoker) SomeMethod);
见How to Use ISynchronizeInvoke interface?
我在我的 UWP 应用程序中使用 x:Bind(编译绑定)将 TextBlock 绑定到 ViewModel 中的整数 属性,该整数由值转换器转换为字符串。我在工作线程的 ViewModel 中使用一个方法来设置属性并调用 PropertyChanged 事件。但是,我得到一个异常(具体来说,它在 MainPage.g.cs 文件的 XamlBindingSetters class 中)说 "The application called an interface that was marshalled for a different thread." According to this post,这在 WPF 中应该工作得很好; WinRT/UWP 中是否删除了这种易用性功能,还是我做错了什么?
这正是我正在做的。
我的属性是这样定义的:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set
{
Set(ref myProperty, value);
}
}
Set 方法是模板 10 库的一部分,定义如下:
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(属性Name) 以确保应用程序实际上是 运行(不处于设计模式),然后引发 PropertyChanged 事件。
我从工作线程设置 属性:
MyProperty = newValue;
当它到达 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 = ...) 并告诉我应用程序调用了一个为不同线程编组的接口。我做错了什么?
您需要在 UI 线程中执行所有图形对象。
第一个解决方案,使用MVVM Light框架。
见Simple example of DispatcherHelper
第二种方案,使用ISynchronizeInvoke.
典型用法:
obj.Invoke((MethodInvoker) SomeMethod);
见How to Use ISynchronizeInvoke interface?