2016-07-10 74 views
1

同样的问题已经在这个网站上被询问了很多次,我读了大部分。但是我有一个特殊的问题(也许是?),在经过几个小时的挣扎和阅读SO帖子之后无法解决问题。WPF-将TextBlock绑定到按钮

问题是 - 简单地解释,我有一个WPF窗体,其中包含一个Connect按钮。如果按下该按钮,则文本块必须出现在该窗体上,显示单词“正在连接...”。按下按钮后,一些握手操作将在相关的C#代码中完成,这需要一些时间。如果程序无法连接,则文本块必须更改为“失败!”。否则,它会更改为“成功”。

<Window x:Class="WpfTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="300" Width="200"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition /> 
      <RowDefinition /> 
     </Grid.RowDefinitions> 
     <Button x:Name="connecting" Content="Connect" FontWeight="Bold" Click="startConnection" 
       Width="60" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0"/> 
     <TextBlock x:Name="comm_stat" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" 
       Text="{Binding Content}"/> 
    </Grid> 
</Window> 

和C#代码(由this answer启发):

using System; 
using System.Text; 
using System.Windows; 
using System.ComponentModel; 

namespace WpfTest 
{ 
    public class DynamicObj : INotifyPropertyChanged 
    { 
     public DynamicObj() : this(string.Empty) { } 
     public DynamicObj(string txt) { Content = txt; } 
     private string _name; 
     public string Content 
     { 
      get { return _name; } 
      set { 
       _name = value; 
       OnPropertyChanged("Content"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     public void OnPropertyChanged(string PropertyName) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(PropertyName)); 
     } 
    } 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = this; 
      comm_stat.DataContext = new DynamicObj(); 
     } 
     private void startConnection(object sender, RoutedEventArgs e) 
     { 
      comm_stat.Text = "Connecting..."; 

      bool connect2device = false; 
      // do the handshaking operations. the result is then assigned to connect2device 

      comm_stat.Text = connect2device ? "Succeed." : "Failed!"; 
      // some other operations 
     } 
    } 
} 

现在的问题是,每当我按一下按钮

现在为这个简单的问题,我在我的XAML中写道,文本块中不会出现文本。因为程序等待startConnection方法达到其结尾,然后更新绑定文本块。但我希望文本块在之后按下按钮之后更改。我怎样才能做到这一点?

+0

看来你开始在UI线程上耗时的操作。因此,UI线程被卡住等待您的操作完成,无法更新任何绑定。 –

+0

你有什么建议?我是C#noob @ qqww2 –

+1

只需使用Task.Run启动操作并等待它。你可以在google上搜索'async - await'来学习基础知识。 –

回答

3

可以使用BackgroundWorker这样:

bool connect2device = false; 

private void startConnection(object sender, RoutedEventArgs e) 
{ 
    comm_stat.Text = "Connecting..."; 

    // do the handshaking operations. the result is then assigned to connect2device 

    BackgroundWorker worker = new BackgroundWorker(); 
    worker.DoWork += DoWork; 
    worker.RunWorkerCompleted += Completed; 

    worker.RunWorkerAsync(); 
} 

private void Completed(object sender, RunWorkerCompletedEventArgs e) 
{ 
    comm_stat.Text = connect2device ? "Succeed." : "Failed!"; 
} 

private void DoWork(object sender, DoWorkEventArgs e) 
{ 
    //Change with actual work. 
    Thread.Sleep(1000); 
    connect2device = true; 
} 

一边注意的是,你实际上并不使用绑定来更改文本。 comm_stat.Text = "Connecting...";直接设置文本属性,并且DynamicObj对象根本不使用。在MVVM上阅读一些教程可能会对您有所帮助。

相关问题