2010-10-19 27 views
17

Tôi đang cố gắng đưa ra một cách kín đáo để hiển thị các thông báo lỗi nhỏ cho người dùng. Vì vậy, tôi đã thêm một statusbar mẫu của tôi,WPF Làm mờ văn bản thanh trạng thái sau X giây?

<StatusBar Margin="0,288,0,0" Name="statusBar" Height="23" VerticalAlignment="Bottom"> 
     <TextBlock Name="statusText">Ready.</TextBlock> 
    </StatusBar> 

Và sau đó khi họ nhấp vào nút "Add", nó nên làm một số công cụ, hoặc hiển thị một thông báo lỗi:

private void DownloadButton_Click(object sender, RoutedEventArgs e) 
{ 
    addressBar.Focus(); 
    var url = addressBar.Text.Trim(); 
    if (string.IsNullOrEmpty(url)) 
    { 
     statusText.Text = "Nothing to add."; 
     return; 
    } 
    if (!url.Contains('.')) 
    { 
     statusText.Text = "Invalid URL format."; 
     return; 
    } 
    if (!Regex.IsMatch(url, @"^\w://")) url = "http://" + url; 
    addressBar.Text = ""; 

Nhưng tin nhắn chỉ ngồi đó trong cuộc đời của ứng dụng ... Tôi nghĩ tôi nên đặt lại sau khoảng 5 giây ... làm cách nào tôi có thể đặt hẹn giờ để làm điều đó?

Phần thưởng: Làm cách nào để tạo hiệu ứng mờ dần khi tôi làm như vậy?


Tôi đã tạo một System.Timers.Timer,

private Timer _resetStatusTimer = new Timer(5000); 

    void _resetStatusTimer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     statusText.Text = "Ready"; 
    } 

Nhưng sự kiện Elapsed chạy trên một sợi khác với giao diện người dùng, mà nó không thích ... làm thế nào để tôi nhận được xung quanh đó?

Trả lời

36

Bạn có thể sử dụng Bảng phân cảnh để thực hiện thủ thuật.

<Storyboard x:Key="Storyboard1"> 
     <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="statusBarItem"> 
      <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
      <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/> 
      <EasingDoubleKeyFrame KeyTime="0:0:3" Value="1"/> 
      <EasingDoubleKeyFrame KeyTime="0:0:4" Value="0"/> 
     </DoubleAnimationUsingKeyFrames> 
    </Storyboard> 

Khi thông báo được hiển thị, bạn chỉ cần gọi theo cách lập trình phương thức Bắt đầu của StoryBoard hoặc chèn trình kích hoạt như sau.

<Window.Triggers> 
    <EventTrigger RoutedEvent="TextBoxBase.TextChanged" SourceName="textBox"> 
     <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/> 
    </EventTrigger> 
</Window.Triggers> 

EDIT: Một lựa chọn khác là để làm như thế này:

<TextBlock Name="statusText" Text="{Binding Path=StatusBarText, NotifyOnTargetUpdated=True}"> 
     <TextBlock.Triggers> 
      <EventTrigger RoutedEvent="Binding.TargetUpdated"> 
       <BeginStoryboard> 
        <Storyboard> 
         <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity"> 
          <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
          <EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="1"/> 
          <EasingDoubleKeyFrame KeyTime="0:0:4" Value="1"/> 
          <EasingDoubleKeyFrame KeyTime="0:0:5" Value="0"/> 
         </DoubleAnimationUsingKeyFrames> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
     </TextBlock.Triggers> 

Sau đó, để tạo ra một DependencyProperty gọi StatusBarText trong trường hợp này được thực hiện như sau:

public string StatusBarText 
    { 
     get { return (string)GetValue(StatusBarTextProperty); } 
     set { SetValue(StatusBarTextProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for StatusBarText. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty StatusBarTextProperty = 
     DependencyProperty.Register("StatusBarText", typeof(string), typeof(MyOwnerClass), new UIPropertyMetadata("")); 

Hy vọng điều này sẽ hữu ích.

+0

Tôi nên đặt rằng ' '? Bất cứ nơi nào trong XAML? – mpen

+1

Nó có thể nằm trong bất kỳ từ điển tài nguyên nào trong cửa sổ chứa 'statusBarItem'. Có lẽ không có lý do gì để không đặt nó trong 'Window.Resources'. –

+0

Cảm ơn Robert .. làm cho nó hoạt động ngay bây giờ! Nhưng có cách nào tôi có thể buộc nó vào sự kiện statusText.Changed trực tiếp trong XAML? Sau đó, tôi sẽ không phải gọi bất kỳ phương thức 'Begin()' nào, sẽ không phải tìm tài nguyên trong đoạn mã sau, và tôi sẽ không bao giờ phải lo lắng về việc quên bắt đầu bảng phân cảnh ... – mpen

7

Bộ hẹn giờ của bạn là một cách tiếp cận tốt và thậm chí bạn đã xác định được sự cố của mình: bạn chỉ cần một cách để truy cập statusText.Text trên chuỗi giao diện người dùng. (Trong WPF, các chủ đề khác với chuỗi giao diện người dùng bị cấm truy cập vào các phần tử giao diện người dùng). Ở đây có WPF Dispatcher để giải cứu:

http://msdn.microsoft.com/en-us/magazine/cc163328.aspx#S5

Bạn có thể sử dụng lớp DispatcherTimer để thực hiện chính xác những gì bạn đã cố gắng (đây là mã của họ):

// Create a Timer with a Normal Priority 
_timer = new DispatcherTimer(); 

// Set the Interval to 2 seconds 
_timer.Interval = TimeSpan.FromMilliseconds(2000); 

// Set the callback to just show the time ticking away 
// NOTE: We are using a control so this has to run on 
// the UI thread 
_timer.Tick += new EventHandler(delegate(object s, EventArgs a) 
{ 
    statusText.Text = string.Format(
     "Timer Ticked: {0}ms", Environment.TickCount); 
}); 

// Start the timer 
_timer.Start(); 
+0

Cảm ơn! Điều này hoạt động tốt, và nó đã được khá dễ dàng để làm. AS-CII đã đi cho tiền thưởng mặc dù! – mpen

Các vấn đề liên quan