2010-01-27 159 views
0

我有一個應用程序,當一個人鍵入或選擇一個列表框時,會有一部分屏幕動態更新到新視圖。WPF框架在單獨的線程?

問題是因爲WPF在單線程中運行所有內容,顯示視圖可能會干擾打字或導航,從而導致應用程序響應性降低。我想要做的是在不同的線程中運行視圖部分。

我的第一個想法是使用一個運行在不同線程上的窗口,但不僅僅是一個黑客的問題,而是窗口失去焦點並在單擊主窗口時放置在主窗口後面的問題。我可以做到最頂層,但我也需要在其前面放置其他窗口。

那麼實現這一目標的最佳方法是什麼?我可以將視圖放在一個框架中並在不同的線程中運行它嗎?

回答

1

您可以在後臺線程中加載/生成數據,然後使用Dispatcher.BeginInvoke更新UI。

0

我會建議你使用你想要顯示的這塊屏幕的Visibility屬性,並且在用戶鍵入或選擇時使用觸發器將它從不可見或摺疊設置爲可見。或者你可以動畫不透明屬性來產生一個很酷的衰落效果;-)我將添加一些代碼來說明這一點。 編輯:消費backgroundtask,像文件操作的時候,可以使用與線程問題恐怕一個BackgroundWorker

<Window x:Class="VisibleOnTypingSpike.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
<StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <Label Name="TypingSnooper" 
       Visibility="{Binding TypingSnooperVisibility}"> 
      You are typing!</Label> 
     <Label> 
      <Label.Style> 
       <Style> 
        <Setter Property="Label.Opacity" Value="0"/> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding HasListBoxNewSelection}" Value="True"> 
          <DataTrigger.EnterActions> 
           <BeginStoryboard > 
            <Storyboard> 
             <DoubleAnimation From="0" To="1" 
                 Duration="0:0:1" 
                 Storyboard.TargetProperty="Opacity"/> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.EnterActions> 
          <DataTrigger.ExitActions> 
           <BeginStoryboard > 
            <Storyboard> 
             <DoubleAnimation From="1" To="0" 
                 Duration="0:0:1" 
                 Storyboard.TargetProperty="Opacity"/> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.ExitActions> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </Label.Style> 
      You selected! 
     </Label> 
    </StackPanel> 
    <TextBox TextChanged="TextBox_TextChanged"></TextBox> 
    <ListBox Name="SimpleListBox" 
      SelectionChanged="SimpleListBox_SelectionChanged"> 
     <ListBoxItem>1</ListBoxItem> 
     <ListBoxItem>2</ListBoxItem> 
    </ListBox> 
</StackPanel> 

using System.Windows; 
    using System.Windows.Controls; 

namespace VisibleOnTypingSpike 
{ 
    public partial class Window1 : Window 
    { 
     public Visibility TypingSnooperVisibility 
     { 
      get { return (Visibility)GetValue(TypingSnooperVisibilityProperty); } 
      set { SetValue(TypingSnooperVisibilityProperty, value); } 
     } 

     public static readonly DependencyProperty TypingSnooperVisibilityProperty = 
      DependencyProperty.Register("TypingSnooperVisibility", 
             typeof(Visibility), 
             typeof(Window1), 
             new UIPropertyMetadata(System.Windows.Visibility.Collapsed)); 

     public bool HasListBoxNewSelection 
     { 
      get { return (bool)GetValue(HasListBoxNewSelectionProperty); } 
      set { SetValue(HasListBoxNewSelectionProperty, value); } 
     } 

     public static readonly DependencyProperty HasListBoxNewSelectionProperty = 
      DependencyProperty.Register("HasListBoxNewSelection", 
             typeof(bool), 
             typeof(Window1), 
             new UIPropertyMetadata(false)); 

     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = this; 
     } 

     private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      var textbox = (TextBox) sender; 
      if (textbox.Text.Length > 0) TypingSnooperVisibility = Visibility.Visible; 
      else TypingSnooperVisibility = Visibility.Hidden; 
     } 

     private void SimpleListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      HasListBoxNewSelection = true; 
      HasListBoxNewSelection = false; 
     } 
    } 
} 
+0

不過犯規的幫助來完成,問題是,僅僅功能比如加載一個Document可以在界面中產生「stutter」,我真的需要在一個單獨的線程中運行它 – Homde 2010-01-27 15:12:05

+0

我總是加入代碼;-)比如加載一個可以使用BackgroundWorker完成的文檔。我在上面的答案中包含了一個msdn的鏈接。 WPF永遠不會允許同一UI的兩部分在單獨的線程上運行。您必須在後臺執行耗時的任務,然後通過新數據準備就緒的事件通知UI。 – Dabblernl 2010-01-27 15:25:41

+0

當然,我可以將窗戶層疊在一起,每個窗戶都運行着自己的線程,甚至是透明的。這有點黑客,但它的作品。我現在看到爲什麼一個框架無法在自己的線程中運行的原因 – Homde 2010-01-27 15:40:16