2016-04-08 45 views
-2

標題說這一切...如何將按鈕更改爲動畫的加載圖標?

我老實說,在這裏輸了...我使用WPF來做到這一點。我試過使用後臺工作者,線程,Dispatcher.BeginInvoke()和異步等待來實現我的目標,但無濟於事......我在異步等待中解決,因爲我認爲這是更簡單的在這裏發佈.. 。

這裏是我的代碼:

C#代碼背後:

private async void btnLogin_Click(object sender, RoutedEventArgs e) 
{ 
    btnLogin.Visibility = Visibility.Hidden; 
    RollingIcon.Visibility = Visibility.Visible; 

    await DoLogin(); 

    btnLogin.Visibility = Visibility.Visible; 
    RollingIcon.Visibility = Visibility.Collapsed; 
} 

private Task DoLogin() 
{ 
    return TaskEx.Run(() => { 
     //code for validation if no nulls 
     this.ViewModel.ValidateUserCredentials(); 
    }); 
} 

XAML

<Button x:Name="btnLogin" 
     Content="Login" 
     Margin="10,10,10,0" 
     IsDefault="True" 
     Foreground="White" 
     Background="#FF757575" 
     Click="btnLogin_Click" /> 
<local:SpinningAnimation x:Name="RollingIcon" Width="40" Height="40" Margin="10,10,10,0" Visibility="Collapsed"> 

</local:SpinningAnimation > 

顯然,System.InvalidOperationException會彈出因爲視圖模型在日創建e當我試圖在另一個線程上填充主線程時。

請指引我正確的道路,並把我從黑暗的一面...

任何可以理解的。

TIA

+1

如果使用MVVM模式,我覺得你有什麼可怕的錯誤。你正試圖從你的ViewModel的View(UI-Thread)中運行一個任務嗎?即使Visibilty應該綁定到屬性..如果你需要隱藏,使用另一個轉換器。對於登錄,我會寫一個服務類或類似的東西,並將Button綁定到使用它的命令。 –

+0

@丹尼爾 - 這給了我一個主意。將嘗試它!謝謝!儘管downvote真的傷害了這麼多.. –

+0

沒問題..爲了更好的理解,請參閱一些(基本的)MVVM示例以達到您的目的,就像許多已發佈的一樣。如果您確實需要從另一個線程訪問某些內容,則可以使用Dispatcher Invoke ..但在此之前,最好理解線程。我沒有給你一個讚譽,哈哈 –

回答

0

回答這個問題:

感謝丹尼爾,我意識到,把一個新的線程在VM比查看更多合適的。我返工我的設計,這是它看起來像現在:

VM

public void ValidateUserCredentials() 
     { 
      BackgroundWorker bgw = new BackgroundWorker(); 
      bgw.DoWork += new DoWorkEventHandler(Bgw_DoWork); 
      bgw.RunWorkerCompleted += Bgw_RunWorkerCompleted; 
      bgw.RunWorkerAsync(); 
     } 
     private void Bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if (IsLoginSuccessful == true) 
      { 
       _controller.CloseViewModel(this); 
       _controller.InitWincollect(); 
      } 
     } 

     private void Bgw_DoWork(object sender, DoWorkEventArgs e) 
     { 
      ShowBusyIcon = true; 
      IsLoginSuccessful = _controller.ValidateUserCredential(); 
     } 
     bool _isLoginSuccessful = false; 
     private bool _showBusyIcon; 

     public bool ShowBusyIcon 
     { 
      get { return _showBusyIcon; } 
      set { _showBusyIcon = value; NotifyPropertyChanged("ShowBusyIcon"); } 
     } 

     public bool IsLoginSuccessful 
     { 
      get { return _isLoginSuccessful; } 
      set { _isLoginSuccessful = value; NotifyPropertyChanged("IsLoginSuccessful"); } 
     } 

視圖(XAML)

 <Button x:Name="btnLogin" 
       Content="Login" Visibility="{Binding ShowBusyIcon, Converter={StaticResource inverseVisibilityConverter}}" /> 
     <local:SpinningAnimation x:Name="RollingIcon" 
            Grid.Column="1" 
            Width="40" Height="40" 
            Margin="10,10,10,0" 
            Visibility="{Binding ShowBusyIcon, Converter={StaticResource bool2VisibilityConverter}}" 
            Style="{DynamicResource SpinningAnimationStyle1}" />