2012-05-23 94 views
0

我有一個<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

你調用冗長的操作在一個單獨的線程?如果沒有,它將在UI線程上運行,調用Dispatcher上的文本更改將不會執行任何操作,因爲它正在等待冗長的操作完成。看到一些輔助操作將會有所幫助。另外,你可能想看看BackgroundWorker類和它的ProgressChanged事件。 –

回答

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(); 
+0

no no success ...同樣我把冗長的操作部分放在Dispatcher.BeginInvoke中... – BreakHead

+0

讓我們看看你的代碼,看看我的更新... – animaonline

-1

用你的 「漫長」 操作之前的Application.DoEvents()

+0

在我的WPF應用程序中沒有Applicaion.DoEvents()... – BreakHead

+0

這是錯誤的,System.Windows.Forms.Application.DoEvents()不應該用於那個。冗長的操作不應該在主線程上運行。它可能會工作,但應該避免這樣做。 – animaonline

+0

這是編碼器的選擇!我不確定在wpf中是否有'Application.DoEvents()'。非常抱歉!我的答案將使用['BackgroundWorker'](http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker.aspx)用於您的工作。它比使用MultiThreading更好! – Writwick

0

Dispatcher.BeginInvoke()沒有幫助的原因是因爲即使它的運行方式是asyronronously,它仍然會在主/ 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); 
     } 
    } 
}