2013-01-10 45 views
5

我試圖綁定WPF中ProgressBar的value屬性。我有一個按鈕,用於爲ProgressBar的Value增加數據綁定int屬性。當我按下按鈕時,它應該使ProgressBar的值從1增加到100.但是...它似乎並沒有工作,我不知道我在做什麼錯誤。這是我的XAML ...WPF ProgressBar與值數據綁定

<Window x:Class="ProgressBarExample2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="250" Width="400" Background="WhiteSmoke"> 
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center"> 
    <Button Name="goButton" Height="30" Width="50" Margin="0,10,0,50" Click="goButton_Click">GO!</Button> 
    <ProgressBar Name="progressBar" Width="300" Height="30" Value="{Binding Percent, UpdateSourceTrigger=PropertyChanged}" /> 
</StackPanel> 

,這裏是我的背後...代碼

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void NotifyPropertyChange(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 

    private int percent = 0; 
    public int Percent 
    { 
     get { return this.percent; } 
     set 
     { 
      this.percent = value; 
      NotifyPropertyChange("Percent"); 
     } 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 


    private void goButton_Click(object sender, RoutedEventArgs e) 
    { 
     for (Percent = 0; Percent <= 100; Percent++) 
     { 
      Thread.Sleep(50); 
     } 
    } 
} 
+0

可以或許嘗試添加按鈕一timer-點擊啓動計時器的Click事件中使用它。在定時器回調增量中,具有正確的數據綁定的Percent-應該可以工作。定時器回調是在後臺線程,所以你的主線程是免費更新進度條 – Sarang

回答

1

沒有代碼(發佈),設置窗口的DataContext的(或StackPanel中)。

爲了確定原因,請查看輸出窗口中的綁定錯誤。


,此外,

private void goButton_Click(object sender, RoutedEventArgs e) 
{ 
    for (Percent = 0; Percent <= 100; Percent++) 
    { 
     Thread.Sleep(50); 
    } 
} 

此塊消息處理使您的應用程序將是 '反應遲鈍',持續5秒。沒有輸入處理和屏幕更新將不會發生。忙碌的循環在事件驅動的GUI中根本不好。

將此代碼移到Backgroundworker或使用計時器。

+0

啊,這就是我忘了......好吧,固定它的種類...但它並沒有實時更新值...現在它只是從0跳到100%,即使我增加睡眠時間... – user1451495

+0

也爲此添加了答案。 –

6

Thread.Sleep阻止UI線程並停止進度條的動畫。

您可以使用以下命令暫停執行而不會阻塞UI線程。與Wait(50)

編輯替換您的通話Thread.Sleep(50):刪除了委託

/// <summary> 
/// Stop execution for a specific amount of time without blocking the UI 
/// </summary> 
/// <param name="interval">The time to wait in milliseconds</param> 
public static void Wait(int interval) 
{ 
    ExecuteWait(() => Thread.Sleep(interval)); 
} 

public static void ExecuteWait(Action action) 
{ 
    var waitFrame = new DispatcherFrame(); 

    // Use callback to "pop" dispatcher frame 
    IAsyncResult op = action.BeginInvoke(dummy => waitFrame.Continue = false, null); 

    // this method will block here but window messages are pumped 
    Dispatcher.PushFrame(waitFrame); 

    // this method may throw if the action threw. caller's responsibility to handle. 
    action.EndInvoke(op); 
} 
+0

浪費了一整天的時間,試圖找出爲什麼UI被凍結。新手我。 – NotAgain

0

有沒有綁定其他的解決方案。 你可以聲明一個委託

private delegate void UpdateProgressBarDelegate(System.Windows.DependencyProperty dp, Object value);

,並在按鈕

private void goButton_Click(object sender, RoutedEventArgs e) 
     { 
      //Configure the ProgressBar 
      progressBar.Minimum = 0; 
      progressBar.Maximum = 100; 
      progressBar.Value = 0; 

      //Stores the value of the ProgressBar 
      double value = 0; 

      //Create a new instance of our ProgressBar Delegate that points 
      // to the ProgressBar's SetValue method. 
      UpdateProgressBarDelegate updatePbDelegate = new UpdateProgressBarDelegate(progressBar.SetValue); 

      //Tight Loop: Loop until the ProgressBar.Value reaches the max 
      do 
      { 
       value += 1; 

       /*Update the Value of the ProgressBar: 
        1) Pass the "updatePbDelegate" delegate that points to the ProgressBar1.SetValue method 
        2) Set the DispatcherPriority to "Background" 
        3) Pass an Object() Array containing the property to update (ProgressBar.ValueProperty) and the new value */ 
       Dispatcher.Invoke(updatePbDelegate, 
        System.Windows.Threading.DispatcherPriority.Background, 
        new object[] { ProgressBar.ValueProperty, value }); 

      } 
      while (progressBar.Value != progressBar.Maximum); 
     }