WPF-将TextBlock绑定到按钮

时间:2016-07-10 11:00:30

标签: c# wpf xaml data-binding

本网站已经多次询问过同样的问题,我已经阅读了大部分问题。但是我有一个特殊的问题(也许?)在经过几个小时的挣扎和阅读SO帖后无法弄明白。

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

现在,对于这个简单的问题,我在我的XAML中写道:

<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
        }
    }
}

现在的问题是,每当我点击按钮时,文本块中都不会出现文字。因为程序等待startConnection方法到达其结尾,然后更新绑定的文本块。但我希望文本块在按下按钮后立即更改。我怎么能这样做?

1 个答案:

答案 0 :(得分: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...";直接设置text属性,并且根本不使用DynamicObj对象。阅读一些关于MVVM的教程可能对你有好处。