WPF递增绑定属性在for循环中没有通知UI,并阻塞了它

本文关键字:UI 通知 绑定 属性 循环 for WPF | 更新日期: 2023-09-27 18:08:01

我使用wpf和mvvm有非常奇怪的问题。假设你有一个textbox绑定到视图模型上的Counter属性。按钮在视图模型上改变属性,引发PropertyChanged事件,UI被更新。好吧,这正是发生了什么,如果我做的东西像Counter++但是,当我尝试这样做在for循环,改变Counter属性10次一次点击,它阻塞UI和显示只是最后一个字符串在循环结束…下面是代码:

public class MainViewModel : INotifyPropertyChanged
{
    private int counter;
    public int Counter
    {
        get { return counter; }
        set { counter = value; Notify("Counter"); }
    }
    public MainViewModel()
    {
        Counter = 0;
    }
    public void inc()
    {
        for (int i = 0; i < 10000; i++)
        {
            Counter++;
        }           
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void Notify(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void button_Click(object sender, RoutedEventArgs e)
    {
        var button = sender as Button;
        var dataContext = button.DataContext as MainViewModel;
        dataContext.inc();
    }
}

<Window x:Class="WpfTests.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:i="http://schemas.microsoft.com/prototyping/2010/interactivity"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfTests"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <local:MainViewModel></local:MainViewModel>
</Window.DataContext>
<Grid>
    <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="40,106,0,0" TextWrapping="Wrap" Text="{Binding Counter}" VerticalAlignment="Top" Width="120"/>
    <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="287,106,0,0" VerticalAlignment="Top" Width="75" Click="button_Click">
    </Button>
</Grid>

WPF递增绑定属性在for循环中没有通知UI,并阻塞了它

好吧,这就是发生的事情,如果我做类似于Counter++但是,当我尝试在for循环中这样做时,一次点击改变Counter属性10次,它会阻塞UI并在循环结束时显示最后一个字符串

当你改变Counter属性时,你是在UI线程中做的。在此期间,UI线程被阻塞。当第一次更改完成后,您将再次更新Counter属性=> UI线程再次阻塞。