我内部有<Border>
我有<Image>
和<Textblock>
,我正在尝试更改Mouseleftbutton上的文本块文本,因为里面有一些更长的操作此单击事件,文本块的文本在此操作完成之前不会更改。
我也试过Dispatcher.BeginInvoke()
,但没有成功。
这是我的代码:
<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
}
}
答案 0 :(得分:0)
在线程上执行冗长的操作并使用
分派器
相应地更新UI。
示例代码:
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();
答案 1 :(得分:0)
Dispatcher.BeginInvoke()没有帮助的原因是因为即使它是asycnronously运行,它仍然在主/ UI线程上运行。使用BackgroundWorkerThread类在后台线程上执行冗长的操作。
我编写了一些示例来证明:
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:
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);
}
}
}
答案 2 :(得分:-1)
在“漫长”操作之前使用Application.DoEvents()
!