简体   繁体   English

单击时更改文本块文本

[英]Change textblock text on click

I have a <Border> inside that I have an <Image> and a <Textblock> , and I am trying to change the textblock text on Mouseleftbutton down, since there is some more lengthy operation inside this click event, text of text block doesn't change till this operation get completed.我有一个<Border>里面有一个<Image>和一个<Textblock> ,我试图改变 Mouseleftbutton 上的 textblock 文本,因为在这个 click 事件中有一些更冗长的操作,文本块的文本没有在此操作完成之前不要更改。

also I tried Dispatcher.BeginInvoke() , but no success.我也试过Dispatcher.BeginInvoke() ,但没有成功。

Here is my Code :这是我的代码:

<Border x:Name="btnReadMe" Grid.Row="0" Style="{StaticResource BorderStyle1}" MouseLeftButtonDown="btnReadMe_MouseLeftButtonDown" MouseLeftButtonUp="btnReadMe_MouseLeftButtonUp" >
    <Border.Background>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="#46c746" Offset="0"/>
            <GradientStop Color="#129312" Offset="1"/>
        </LinearGradientBrush>
    </Border.Background>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="6*"/>
        </Grid.ColumnDefinitions>
        <Image Grid.Column="0" Source="/CareFamily.AtHome;component/Resources/read_message-read_it.png" Margin="5,15" >
            <Image.RenderTransform>
                <ScaleTransform ScaleX="1" ScaleY="1"/>
            </Image.RenderTransform>
        </Image>
        <StackPanel Grid.Column="1" Margin="0,10,0,10"  VerticalAlignment="Center">
            <TextBlock Name="tbReadToMe" Text="Read to Me" Style="{StaticResource TextBlockStyle1}" Margin="0,0,0,0"  />
        </StackPanel>
    </Grid>
</Border>

SpVoice voice;
private void btnReadMe_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (voice == null)
        voice = new SpVoice();


    string readMessageState = tbReadToMe.Text;
    switch (readMessageState)
    {
        case "Read to Me":
            {
                tbReadToMe.Text = "Pause";
                break;
            }

        case "Pause":
            {
                tbReadToMe.Text = "Resume";
                voice.Pause();
                break;
            }

        case "Resume":
            {
                tbReadToMe.Text = "Pause";
                voice.Resume();
                break;
            }
        default:
            {
                tbReadToMe.Text = "Read to Me";
                break;
            }
    }


    if (!string.IsNullOrEmpty(Msg.Subject))
    {
        voice.Speak(Msg.Subject, SpeechVoiceSpeakFlags.SVSFDefault);
    }
    if (!string.IsNullOrEmpty(Msg.Body))
    {
        voice.Speak(Msg.Body, SpeechVoiceSpeakFlags.SVSFDefault); // Length operation
    }
}

Execute your lengthy operation on a Thread and use the在线程上执行冗长的操作并使用

Dispatcher调度员

to update the UI accordingly.相应地更新用户界面。

Example Code:示例代码:

var opThread = new Thread(delegate()
{
    //your lengthy operation

    tbReadToMe.Dispatcher.Invoke(new Action(delegate
    {
        tbReadToMe.Text = "Pause";
    }));

    //your lengthy operation

    tbReadToMe.Dispatcher.Invoke(new Action(delegate
    {
        tbReadToMe.Text = "etc...";
    }));
});

opThread.Start();

The reason Dispatcher.BeginInvoke() didn't help is because even though it operates asycnronously, it still does it on the main/UI thread. Dispatcher.BeginInvoke() 没有帮助的原因是,即使它异步运行,它仍然在主/UI 线程上运行。 Do your lengthy operation on a background thread using the BackgroundWorkerThread class.使用 BackgroundWorkerThread 类在后台线程上执行冗长的操作。

I worked up a little sample to demonstrate:我整理了一个小样本来演示:

Window1.xaml: Window1.xaml:

<Window x:Class="BackgroundWorkerExample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="663">
<Grid>
    <TextBox PreviewMouseDown="textBox1_PreviewMouseDown" Height="38" Margin="24,34,26,0" Name="textBox1" VerticalAlignment="Top" FontSize="24">
        The quick Velociraptor jumped over the torpid tapir.
    </TextBox>
</Grid>

Window1.xaml.cs: Window1.xaml.cs:

using System.Windows;
using System.Windows.Input;
using System.ComponentModel;
using System.Threading;
using System.Windows.Media;
using System;

namespace BackgroundWorkerExample
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }


        void _asyncSpeakerThread_DoWork(object sender, DoWorkEventArgs e)
        {
            // Change color of text to Red to indicate Start of operation
            this.Dispatcher.BeginInvoke(new Action(() =>  { textBox1.Foreground = Brushes.Red; }));

            string text = e.Argument as string;
            //voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault); // Lengthy operation 
            Thread.Sleep(1000); // Simulate lengthy operation

            // Change color of text to Black to indicate End of operation
            this.Dispatcher.BeginInvoke(new Action(() => { textBox1.Foreground = Brushes.Black; }));
        }

        private void textBox1_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            BackgroundWorker bw = new BackgroundWorker();

            bw.DoWork += new DoWorkEventHandler(_asyncSpeakerThread_DoWork);
            string workerArgument = textBox1.Text;
            bw.RunWorkerAsync(workerArgument);
        }
    }
}

在“冗长”操作之前使用Application.DoEvents()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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