除非暂停,否则不会在xaml中更新PropertyChanged

时间:2018-10-19 12:51:59

标签: c# wpf xaml

这是一个很长的问题,它是一个愚蠢的问题,对于我的应用程序并不重要,但仍然很奇怪。我觉得如果我理解它,将有助于我更好地理解c#/ wpf。

我正在开发一个将excel文件加载到mysql的应用程序。我想在日志文本框中显示何时删除数据库中的行。将新数据加载到数据库后,日志文本框应显示一条消息,其中包含受影响的行数。

文本框绑定到

<TextBox x:Name="ConnectionLogTbx" Text="{Binding ConnectionLogText}" /> 

下面的代码(省略了一些行):ConnectionLogText附加了一个字符串。首先是日期时间+“已删除”。第二次受影响的行数。

插入数据库大约需要2秒钟。我希望出现的是第一个日志消息,然后停顿两秒钟(插入新行时),然后出现第二个日志消息。有趣的是,在插入操作之后,文本框会同时使用两个字符串进行更新。插入操作之前没有日志消息。所显示的时间与预期的一样,中间大约有2秒。

但是,如果我在属性的设置器中添加messagebox.show(并因此创建了pause),则应用程序将按预期运行。第一个日志消息出现在文本框中,单击消息框后,将执行插入操作,然后出现第二个日志消息。

WPF似乎需要休息一下才能更新文本框,但这与我对WPF的了解不一致。

有人可以帮我吗?

public partial class MainWindow : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    private string connectionLogText ="";

    public string ConnectionLogText
        {
            get { return connectionLogText; }
            set
            {
                if (value != connectionLogText)
                {
                    connectionLogText = value;
                    OnPropertyChanged("ConnectionLogText");
                    //MessageBox.Show(""); //THIS IS THE MESSAGEBOX
                 }
            }

       }


    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }


    private void BrowseImportFile_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();
        if (openFileDialog.ShowDialog() == true)
        {
            ImportFilePathTbx.Text = openFileDialog.FileName;
            ImportFileBtn.IsEnabled = true;
        }
    }

    private void ImportFileBtn_Click(object sender, RoutedEventArgs e)
    {
         string connString = 
      ConfigurationManager.ConnectionStrings["connSTring"].ConnectionString;

        MySqlConnection conn = new MySqlConnection(connString);

        conn.Open();
       //here the content of the current db table is deleted
        conn.Close();
        ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + " 
Deleted" + "\r\n";

        conn.Open();

        int numberOfRowsAffected = 0;
        foreach (DataRow dataRow in table.Rows)
       {
            //new data inserted into database numberOfRowsAffected++;
        }
        conn.Close();

        ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + " " + 
numberOfRowsAffected +  " rows inserted" + "\r\n" ;
        }
 }

1 个答案:

答案 0 :(得分:2)

您不能同时在同一线程上更新TextBlock并从数据库中读取记录。

您应该在后台线程上执行数据库操作。最简单的方法是使用Task Parallel Library (TPL)

private async void ImportFileBtn_Click(object sender, RoutedEventArgs e)
{
    string connString = ConfigurationManager.ConnectionStrings["connSTring"].ConnectionString;
    await Task.Run(() =>
    {
        using (SqlConnection conn = new SqlConnection(connString))
        {
            conn.Open();
            //here the content of the current db table is deleted
            conn.Close();
        }
    });

    ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + " Deleted" + "\r\n";

    int numberOfRowsAffected = 0;
    await Task.Run(() =>
    {
        conn.Open();
        foreach (DataRow dataRow in table.Rows)
        {
            //new data inserted into database numberOfRowsAffected++;
        }
        conn.Close();
    });

    ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + " " + numberOfRowsAffected + " rows inserted" + "\r\n";
}