2010-08-06 26 views
28

Để thực hiện môi trường dựa trên tab trong WPF, chúng ta cần chuyển đổi biểu mẫu WPF thành điều khiển người dùng để thực hiện môi trường dựa trên tab, tuy nhiên khi thực hiện điều này, loaded event điều khiển người dùng được gọi là two times.Sự kiện nạp lửa điều khiển người dùng WPF hai lần

Trong khi tìm kiếm trên internet, những người khác cũng chỉ ra vấn đề này. Làm thế nào chúng ta có thể đảm bảo rằng sự kiện được nạp được gọi chỉ một lần, bởi vì khi nó được gọi nhiều lần khởi tạo các điều khiển xảy ra nhiều lần.

Cảm ơn

+0

Tôi đã thử tạo lại ứng dụng này trong ứng dụng .NET 4.0 WPF trống và sự kiện được tải chỉ được kích hoạt một lần. Bạn đã thử nhìn vào ngăn xếp cuộc gọi để xem liệu có điều gì đó kỳ lạ đang xảy ra trong Khuôn khổ .NET trước khi nó kích hoạt sự kiện Đã tải chưa? –

+0

Đặt điều khiển người dùng của bạn bên trong một điều khiển tab và bạn sẽ có thể tạo lại sự cố khi chuyển đổi tab. – Eternal21

Trả lời

36

Như đã giải thích trong blog này, sự kiện Loaded là bắn khi từng một điều khiển sắp được hiển thị (tức là được thêm vào cây trực quan).

Có một số điều khiển có thể khiến cho việc kiểm soát của bạn được tải/dỡ nhiều lần. Ví dụ, WPF TabControl bản địa chỉ hiển thị nội dung của tab đã chọn. Vì vậy, khi bạn chọn một tab mới, nội dung của tab đã chọn trước đó sẽ được tải xuống. Nếu bạn nhấp lại vào tab đã chọn trước đó thì nội dung của nó sẽ được tải lại.

Một công việc xung quanh là sử dụng Boolean để gắn cờ cho dù bạn đã khởi tạo điều khiển của mình, như được đề xuất bởi những người khác. Ngoài ra, bạn có thể sử dụng sự kiện Initialized để thay thế.

+0

Tôi đang sử dụng 'ItemsSource' của TabControl để liên kết nhiều tab và sử dụng' DataTemplate' để ràng buộc ViewModel với các giao diện tab. Trong trường hợp của tôi, không chỉ sự kiện 'Loaded' được bắn lại mà còn cả ** constructor ** của khung nhìn tab được gọi lại. Có vẻ như WPF đang tái tạo điều khiển tab của tôi hoàn toàn mỗi khi tôi chuyển đổi tab. – Felix

2

Đặt một lá cờ loaded trong sự kiện này, và nếu cờ đã được thiết lập, không làm gì cả.

+0

cảm ơn đề xuất của bạn, đây thực sự là vấn đề chính hãng và sự kiện được tải hai lần do tab –

-3

Trên thực tế, đã có một tài sản IsLoaded, vì vậy bạn có thể thêm dòng này vào đầu xử lý sự kiện tải:

If Me.IsLoaded Then Return 
+2

Đừng bận tâm, điều đó không hiệu quả. Bạn sẽ phải sử dụng tài sản của riêng bạn. –

+7

Bạn nên xóa câu trả lời để giữ cho mọi thứ sạch sẽ. – DuckMaestro

+1

Trong trình xử lý sự kiện được tải, rõ ràng, thuộc tính IsLoaded luôn đúng. – Pejman

11

Trình xử lý sự kiện được định tuyến của bạn có thể (và nên) tự xóa khỏi móc Loaded làm điều đầu tiên.

public class MyClass : Window 
{ 
    public MyClass() 
    { 
     Loaded += MyLoadedRoutedEventHandler; 
    } 

    void MyLoadedRoutedEventHandler(Object sender, RoutedEventArgs e) 
    { 
     Loaded -= MyLoadedRoutedEventHandler; 
     /// ... 
    } 
}; 
Các vấn đề liên quan