我用MVVM模式更新界面,增加延时后界面无反应。单次执行后可以更新界面。不知道问题出在哪里?
界面设置如下:
<TextBox x:Name="txtbloc" Grid.Row="0" Width="200" Height="100" Text="{Binding m_person.Name, Mode=OneWay}" Background="#FF9FAF40"></TextBox>
<TextBox Width="200" Height="100" Text="{Binding m_person.Age, Mode=TwoWay ,NotifyOnSourceUpdated=True}" Margin="31,180,569,205" />
<Button x:Name="UpdateBtn" Content="更新" Width="300" Command="{Binding ChangeCommand}" FontSize="24" Margin="230,34,270,385" />
对应的代码如下:
public class ViewModel : MVVMObject
{
public ICommand ChangeCommand { get; set; }
public Person m_person { get; set; } = new Person{ Name="GG",Age=4};
public ViewModel()
{
ChangeCommand = new CommandBase(()=>
{
Hellow();
});
}
private void Hellow()
{
while (true) {//增加无限循环后无法正常更新界面
Task.Delay(1000).GetAwaiter().GetResult();
Random rnd = new Random();
m_person.Age = rnd.Next();
m_person.Name = "ffff" + rnd.Next();
}
}
}
private async void Hellow()
{
while (true)
{
await Task.Delay(1000); // 使用异步等待确保不阻塞主线程
// 在 UI 线程上执行更新界面的操作
Application.Current.Dispatcher.Invoke(() =>
{
Random rnd = new Random();
m_person.Age = rnd.Next();
m_person.Name = "ffff" + rnd.Next();
});
}
}
【以下回答由 GPT 生成】
问题出在无限循环中的Hellow()
方法内部。由于无限循环是同步执行的,会阻塞UI线程,导致界面无法更新。解决这个问题的一种方法是将Hellow()
方法改为异步方法,并使用await Task.Delay
代替同步延迟。以下是修改后的代码示例:
private async void Hellow()
{
while (true)
{
await Task.Delay(1000);
Random rnd = new Random();
m_person.Age = rnd.Next();
m_person.Name = "ffff" + rnd.Next();
}
}
修改后的Hellow()
方法使用async
关键字声明为异步方法,内部使用await Task.Delay(1000)
替代Task.Delay(1000).GetAwaiter().GetResult()
,实现异步延时。这样可以防止阻塞UI线程,使界面能够正常更新。
另外,为了确保界面更新的线程安全,需要在ViewModel的属性属性上使用InvokePropertyChanged
方法来通知UI进行更新。以下是修改后的ViewModel
代码示例:
public class ViewModel : MVVMObject
{
public ICommand ChangeCommand { get; set; }
private Person _person;
public Person m_person
{
get { return _person; }
set {
_person = value;
InvokePropertyChanged("m_person");
}
}
public ViewModel()
{
ChangeCommand = new CommandBase(()=>
{
Hellow();
});
}
private async void Hellow()
{
while (true)
{
await Task.Delay(1000);
Random rnd = new Random();
m_person.Age = rnd.Next();
m_person.Name = "ffff" + rnd.Next();
}
}
}
在m_person
属性的set
方法内部,添加了InvokePropertyChanged("m_person")
来通知UI刷新。
这样修改之后,界面就能在增加了延时和循环后进行正常更新了。
【相关推荐】