2013-01-10 15 views
5

Tôi đang cố gắng databind thuộc tính giá trị của một ProgressBar trong WPF. Tôi có một nút thiết lập để tăng thuộc tính int databound cho Giá trị của ProgressBar. Khi tôi nhấn nút, nó sẽ làm cho giá trị của ProgressBar tăng từ 1 lên 100. Tuy nhiên ... nó dường như không hoạt động và tôi không chắc mình đang làm gì sai. Dưới đây là XAML của tôi ...Tiến trình tiến hành WPF với Databinding giá trị

<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> 

và đây là mã của tôi đằng sau ...

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

bạn có lẽ có thể thử thêm một timer- vào nút bấm bắt đầu hẹn giờ. Trong gọi lại bộ đếm thời gian tăng phần trăm- với ràng buộc dữ liệu thích hợp, điều này sẽ chỉ hoạt động. Gọi lại hẹn giờ đang ở trong chủ đề nền để chủ đề chính của bạn là miễn phí để cập nhật thanh tiến trình – Sarang

Trả lời

1

Không có mã (đăng) mà bộ DataContext của Window (hoặc StackPanel).

Để chắc chắn về nguyên nhân, hãy xem cửa sổ Đầu ra để biết lỗi Binding.


Và ngoài ra,

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

khối xử lý thông báo này để ứng dụng của bạn sẽ là 'không đáp ứng' trong 5 giây. Không xử lý đầu vào và không có cập nhật màn hình sẽ diễn ra. Một vòng lặp bận rộn chỉ đơn giản là không tốt trong một GUI định hướng sự kiện.

Di chuyển mã này sang Backgroundworker hoặc sử dụng Timer.

+0

Ahh thats những gì tôi quên ... ok mà cố định nó loại ... nhưng nó không cập nhật giá trị trong thời gian thực ... bây giờ nó chỉ nhảy từ 0 đến 100 phần trăm ngay cả khi tôi tăng thời gian ngủ ... – user1451495

+0

Đã thêm câu trả lời cho điều đó. –

6

Chủ đề.Sleep đang chặn luồng giao diện người dùng và dừng hoạt ảnh của thanh tiến trình.

Bạn có thể sử dụng thông tin sau để tạm dừng thực thi mà không chặn chuỗi giao diện người dùng. Thay Thread.Sleep(50) cuộc gọi của bạn với Wait(50)

EDIT: Removed đại biểu

/// <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

Đã lãng phí cả ngày cố gắng tìm ra lý do khiến giao diện người dùng bị đóng băng. Newbie tôi. – NotAgain

0

Có nhiều giải pháp khác mà không có sự liên kết dữ liệu. Bạn có thể khai báo một delegate

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

và sử dụng nó trong sự kiện click của nút

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); 
     }