2011-01-16 33 views
24

Tôi đang cố gắng thêm hiệu ứng mờ dần (hoạt ảnh) cho WPF UserControls (mặc dù thay vì cho FrameworkElement, để làm cho nó tổng quát hơn).Sự kiện nào được kích hoạt khi UserControl được hiển thị?

Nếu tôi để cho kích hoạt sự kiện Loaded sự mờ dần ban đầu, hoạt ảnh mờ dần đôi khi sẽ bắt đầu trước khi UserControl được hiển thị. Kết quả là một mớ hỗn độn. Điều đó xảy ra ví dụ nếu UserControl thực hiện một điều gì đó dài (một vài phần mười giây), giống như thực hiện một truy vấn, trong trình xử lý sự kiện được nạp.

Vì vậy, tôi sẽ cần xử lý một số sự kiện mà FrameworkElement/UserControl nhận được khi nội dung được hiển thị và bắt đầu mờ dần sau đó. System.Windows.Window có sự kiện ContentRendered nhưng UserControl thì không. Vì vậy, những gì sự kiện được bắn khi một FrameworkElement (hoặc UserControl) đã được trả lại?

Trả lời

5

Có thể thử IsVisibleChanged, chưa từng sử dụng nhiều.

Sự kiện này không được nâng lên nếu phần tử không được hệ thống bố trí hiển thị, vì các lý do khác với giá trị của thuộc tính IsVisible. Ví dụ: phần tử có thể không có hình ảnh được liên kết.

+1

Nope, nguyên tố này có IsVisible == true đã có trong xử lý sự kiện Loaded. – Batibix

+0

Quá xấu, làm thế nào về kích hoạt phai của bạn bằng tay khi công việc ban đầu của bạn được hoàn thành? –

+1

Vấn đề là - tôi nên kích hoạt nó ở đâu? Sau khi sự kiện được tải được xử lý, điều gì đó vẫn diễn ra lâu dài. Đó có thể là dữ liệu WPF kích hoạt Entity Framework tải từ cơ sở dữ liệu ở đâu đó giữa sự kiện Loaded và hiển thị UserControl. – Batibix

6

Bạn có thể lên lịch đầu Storyboard của bạn với một ưu tiên thấp hơn, ví dụ:

Dispatcher.BeginInvoke(BeginStoryboardAction, DispatcherPriority.ContextIdle); 

Dưới đây là một bài viết mà thảo luận về các vấn đề liên quan đến sử dụng phương pháp này:

18

Hãy thử kiểm tra kích thước trên SizeChanged hoặc LayoutUpdated. Đừng việc khi chiều rộng thực tế hoặc chiều cao không tương đương với 0.

view.LayoutUpdated+=(o,e)=> 
{ 
    if (!loaded && (view.ActualHeight > 0 || view.ActualWidth > 0)) 
    { 
    // You can also unsubscribe event here. 
    loaded =true; 
    } 
} 
+2

Cảm ơn! Rất hữu ích cho các câu hỏi của tôi http://stackoverflow.com/q/18724686/352101 – Bolu

4

Bạn có thể sử dụng IsVisibleChnaged kiện Gán xử lý sự kiện

MyUserControl.IsVisibleChanged += ScheduleUserControl_IsVisibleChanged; 

Trong kiểm tra xử lý sự kiện cho nếu có thể nhìn thấy hay không.

void _IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
{ 
    if ((bool)e.NewValue) 
    { 
     //Visible 
    } 
    else 
    { 
     //Not Visible 
    } 
} 
+0

H.B. đã viết rằng trong câu trả lời của mình. –

+1

.. và tại sao nó không hoạt động. – Riva

10

Năm muộn, nhưng vì tôi đang tìm giải pháp làm việc từ bây giờ vô ích, tôi muốn chia sẻ khám phá của mình.

Nếu bạn muốn sự kiện ContentRendered cho bất kỳ Kiểm soát nào (hoặc bất kỳ Trực quan hoặc thậm chí DependencyObject) nào, bạn phải tìm hiểu về Visual.

tôi sử dụng mã này:

// Wait for Control to Load 
void TestUserControl_Loaded(object sender, RoutedEventArgs e) 
{ 
    // Get PresentationSource 
    PresentationSource presentationSource = PresentationSource.FromVisual((Visual)sender); 

    // Subscribe to PresentationSource's ContentRendered event 
    presentationSource.ContentRendered += TestUserControl_ContentRendered; 
} 

void TestUserControl_ContentRendered(object sender, EventArgs e) 
{ 
    // Don't forget to unsubscribe from the event 
    ((PresentationSource)sender).ContentRendered -= testContentRenderedUC_ContentRendered; 

    // .. 
} 

Bạn phải đợi kiểm soát Loaded khác PresentationSource.FromVisual() trả về null.

Phương thức Dispatcher.BeginInvoke khác nhau không hoạt động liên tục cho tôi. Đôi khi kích hoạt sự kiện được hiển thị của tôi lâu trước khi kiểm soát thực sự được hiển thị.
Điều này làm việc cho tôi mọi lúc.

Tôi biết rằng tôi đang chơi với HwndSource ở đây, mức này khá thấp và tôi không chắc chắn về những tác động có thể xảy ra. (Có lẽ ai đó có kinh nghiệm hơn có thể xây dựng.)

+3

Thật không may, 'ContentRendered' chỉ kích hoạt lần đầu tiên chủ sở hữu' Window' kết thúc hiển thị; điều đó có nghĩa là: nếu 'UserControl' (hoặc bất kỳ' DependencyObject' nào) được hiển thị ** sau khi ** 'ContentRendered' được kích hoạt, nó sẽ không kích hoạt lại. Vấn đề này có thể được phản đối khi bạn có một số điều khiển được tải xuống một cách lười biếng tùy thuộc vào tương tác của người dùng. –

1

Bạn có thể sử dụng Event GotFocus

<i:Interaction.Triggers> 
     <i:EventTrigger EventName="GotFocus"> 
      <i:InvokeCommandAction Command="{Binding ContentControlLoadedCommand}"/> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
Các vấn đề liên quan