【问题标题】:WPF- Binding a TextBlock to a ButtonWPF-将 TextBlock 绑定到按钮
【发布时间】:2016-07-10 11:00:30
【问题描述】:

同样的问题已经在这个网站上被问过很多次了,我已经阅读了其中的大部分内容。但是我有一个特殊的问题(也许?)经过数小时的努力和阅读 SO 帖子后无法解决。

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

现在对于这个简单的问题,我在我的 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 方法结束,然后更新绑定的文本块。但我希望文本块在按下按钮后立即更改 。我该怎么做?

【问题讨论】:

  • 您似乎在 UI 线程上开始了耗时的操作。因此 UI 线程卡在等待您的操作完成,无法更新任何绑定。
  • 你有什么建议?我是 C# 菜鸟@qqww2
  • 只需使用Task.Run 开始操作并等待它。您可以在 google 上搜索 async - await 了解基础知识。
  • 天哪,您的解决方案至少需要 .net 框架 4,而我坚持使用 .net 3.5。还有其他解决方法吗? @qqww2
  • 你可以试试BackgroundWorker

标签: c# wpf xaml data-binding


【解决方案1】:

您可以这样使用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 的教程可能会对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    相关资源
    最近更新 更多