2012-06-01 33 views
1

我找到一個生成的故事板名稱有問題。 我不能使用類變量,因爲此代碼被多次調用,並且返回是異步的。查找動態生成的故事板實例(WPF)

你可以看到我的其他問題的更多信息:Here

我的代碼:

private void refreshPostIt(int index) 
    { 
     Button btn = // Button to rotate 
     Storyboard sb = new Storyboard(); 
     sb.Name = "sb" + postItIndex; 

     Storyboard.SetTarget(rotate, btn); 
     Storyboard.SetTargetName(rotate, btn.Name); 
     Storyboard.SetTargetProperty(rotate, new PropertyPath("(UIElement.RenderTransform).(RotateTransform.Angle)")); 
     sb.Children.Add(rotate); 
     sb.Begin(btn, true); 

     // Asynchronous call 
     BackgroundWorker bgw = new BackgroundWorker(); 
     bgw.DoWork += new DoWorkEventHandler(bgw_DoWork); 
     bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); 
     bgw.RunWorkerAsync(postItIndex); 
    } 
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     int postItIndex = // Retrieved from e.Arguments 
     Button btn = // Find the Button thanks to the postItIndex 

     Storyboard sb = // Here is my problem, how to find the Storyboard 
     if (sb != null) 
     { 
      // Stop rotation 
      //sb.Stop(btn); 
     } 
    } 
+0

你有這個問題,因爲你沒有使用MVVM。如果你的viewmodel有一個「postIt」的集合,每個人都有一個IsRefreshing屬性,你可以BeginStoryBoard並停止它。我會發佈一個答案,解釋如何設置XAML,但適應集合和UI是數據綁定在你身上... –

回答

1

總是可以創建一個從BackgroundWorker的繼承的類,它不密封。向該類添加一個屬性,該屬性包含要傳遞給已完成事件的任何信息。

class StoryboardWorkerArgs 
    { 
     public Storyboard StoryBoard { get; set; } 
     public object Other { get; set; } 
    } 

    class BackgroundWorker2 : BackgroundWorker 
    { 
     public StoryboardWorkerArgs Args { get; set; } 
    } 

然後,您可以在args屬性中設置您的故事板。

BackgroundWorker2 worker = new BackgroundWorker2(); 
worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
worker.Args = new StoryboardWorkerArgs() 
{ 
    StoryBoard = null, /* reference to your storyboard*/ 
    Other = null, /* postItIndex */ 
}; 
worker.RunWorkerAsync(); 

然後在您完成的活動中。

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    BackgroundWorker2 sender2 = sender as BackgroundWorker2; 
    if (sender2 != null) 
    { 
     var story = sender2.Args.StoryBoard; // <- your storyboard. 
    } 
} 
+0

太棒了,你的解決方案工作正常。 但是我只是通過傳遞給調用者的參數類對其進行了修改。謝謝 –

+0

太好了,如果你使用了頁面的答案之一,請爲其他人標記。如果您找到了自己的方法來實現結果,請將其添加爲答案並加以標記,以便其他人在遇到問題時知道如何解決問題。 – Andy

1

如果您使用MVVM來顯示「postIt」 - 啓動和停止故事板將完全在XAML中。

必須在UIItem的DataTemplate以下pseudostyle代表職務:

<Style> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding IsRefreshing}" 
        Value="True"> 
      <DataTrigger.EnterActions> 
       <BeginStoryboard x:Name="rotating"> 
        <Storyboard> 
         <DoubleAnimation... /> 
        </Storyboard> 
       </BeginStoryboard> 
      </DataTrigger.EnterActions> 
      <DataTrigger.ExitActions> 
       <StopStoryboard BeginStoryboardName="rotating" /> 
      </DataTrigger.ExitActions> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

您的ViewModel應該soemthing像(僞):

Class MyApp : INotifyPropertyChanged 
    ObservableCollection<Post> Posts {get;set;} 
    void RefreshPost(int id); 

Class Post : INotifyPropertyChanged 
    bool IsRefreshing {get;set;} 

在窗口中有ItemTemplate中的一個列表框你發佈,並給它ItemsSource Posts集合。

並將窗口的datacontext設置爲MyApp的一個實例。 因此,無論何時您更改某個帖子的IsRrefreshing,UI都會執行其他操作。