简体   繁体   中英

WPF- Binding a TextBlock to a Button

The same questions has been asked many times on this site and I have read most of them. But I have a special problem (maybe?) that couldn't figure it out after hours of struggling and reading SO posts.

The problem is -simply explained, I have a WPF form which contains a Connect button. If this button is pressed a textblock must appear on that form, displaying the word "Connecting...". Upon pressing the button, some handshaking operations are done in the associated C# code which takes some time. If the program fails to connect, the textblock must change to "Failed!". Otherwise, it changes to "Succeed."

Now for this simple problem, I wrote in my 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>

And the C# code (inspired by 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
        }
    }
}

Now the problem is, whenever I click the button, no text is appeared in the textblock. Because the program waits for the startConnection method to reach its end and then updates the bonded textblock. But I want the textblock to change right after pressing the button. How can I do this?

You can use BackgroundWorker as such:

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

One side note is that you actually do not use bindings to change the text. comm_stat.Text = "Connecting..."; sets the text property directly and the DynamicObj object is not used at all. It might be good for you to read a few tutorial on MVVM.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM