c# - uwp - '应用程序调用了一个为不同线程编组的接口
问题描述
我正在尝试使用 MVVM 创建 UWP 聊天。我不断收到此错误:
应用程序调用了为不同线程编组的接口
在我的视图模型中:
public void Notify(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
每次将值设置为绑定到 xaml 中的 TextBlock.Text 属性的字符串属性时,都会发生此函数;
我尝试在视图模型中插入 TextBlock(vm 绑定到其文本属性)并删除 xaml 中的所有绑定并使用此函数:
private async Task LoadMessage(string sender, string message)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
ChatBox += $"{sender}: {message} \n";
});
}
还是一样,只是现在在上面的函数中抛出了异常。
我在搜索答案时找到了另一个调度程序,但似乎 uwp 无法识别它并用红色下划线标记它:
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
//my code
});
我试过了 :
await CoreDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
ChatBox += $"{sender}: {message} \n";
});
但后来我得到了
非静态字段、方法需要对象引用
所以我创建了一个静态类来保存这个函数:
public static void UpdateTextBlock(TextBlock textBlock, string sender, string message)
{
textBlock.Text = $"{sender}: {message}";
}
并将其插入此调度程序。还是不行。仍然:需要对象引用...
我真的希望它是 MVVM,但任何可行的解决方案都是一种祝福。
编辑
今天我尝试回到绑定和 mvvm 模式。我将 LoadMessage 函数包装在这样的任务中:
private async Task<bool> LoadMessage(string sender, string message)
{
bool flag = false;
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
TextBindingProperty += $"{sender}: {message} \n";
flag = true;
});
return flag;
}
_hubProxy.On<string, string>("SendMessage", async (sender, message) =>
{
var result = await Task.Run(() => LoadMessage(sender, message));
});
仅在类中存在相同的异常:MyView.g.cs
在这种方法中:
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; //in this line!!!
}
};
我的视图模型实现 INotifyPropertyChanged
public class UserViewModel : INotifyPropertyChanged
{
private string chatBox;
public string ChatBox
{
get { return chatBox; }
set { chatBox = value; Notify(nameof(ChatBox)); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void Notify(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
绑定到此属性的 xaml 元素如下所示:
<TextBlock Name="chatTbl" Text="{x:Bind userViewModel.ChatBox, Mode=TwoWay}" />
解决方案
解决方案:
所以努力让聊天工作这就是问题所在:
await CoreApplication.MainView
由于聊天与主页位于不同的视图中,因此找不到绑定或 xaml 元素。
我的朋友意识到,为了在其他视图中进行更改,您需要获取其对象,因此,我们将此属性添加到视图模型中:
public CoreApplicationView CurrentView { get; set; }
启动聊天室视图时,我们设置属性:
public UserViewModel userViewModel;
public ChatRoom(UserViewModel userViewModel)
{
this.InitializeComponent();
this.userViewModel = userViewModel;
userViewModel.ChatTbl = chatTbl;
userViewModel.CurrentView = CoreApplication.GetCurrentView();//this line
}
现在,当我们需要在我们使用的视图中进行更改时:
_hubProxy.On<string, string>("SendMessage", async (sender, message) =>
{
await CurrentView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
ChatTbl.Text += $"{sender}: {message} \n";
});
});
所以与其await CoreApplication.MainView
利用await CurrentView.CoreWindow
希望这会帮助我知道它会帮助我的人
推荐阅读
- mysql - 有什么方法可以将独立于 Mysql 版本的 Mysql 服务器连接到 vb.net 应用程序?
- node.js - 在 Postman nodejs 中使用不记名授权
- java - 可选字段不存在与休息请求正文中存在空值的字段之间的区别
- xml - 仅选择 XSLT 中的数字
- c++ - 如何使用 objcopy 将 ARM_ATTRIBUTES 部分添加到二进制文件中
- ios - 方向锁在 xamarin ios 中不起作用
- r - 四个特定行的子集 tibble
- python - 尝试通过 Peak USB 从 Python 向 BUSMASTER 发送消息
- python - 如何在 Python 中将任何图像转换为 CV_32FC1
- javascript - 在 Firestore 云函数中获取文档