2010-09-02 35 views
5

Tôi có Trang trong ứng dụng kiểu điều hướng WPF hiển thị kết quả tìm kiếm. Trang này chứa một số điều khiển ràng buộc dữ liệu. Trang chính nó hoạt động tốt; nó thực hiện tìm kiếm và trả về kết quả. Các điều khiển CheckBox bị ràng buộc dữ liệu hoạt động bình thường.Ràng buộc dữ liệu WPF MVVM bị hỏng sau khi điều hướng trang

Nhưng nếu tôi nhấp vào liên kết kết quả và sau đó nhấp vào nút quay lại để quay lại danh sách kết quả, tất cả các liên kết dữ liệu CheckBox.IsChecked bị hỏng. Các điều khiển ràng buộc dữ liệu khác (ComboBoxes, DatePickers, vv) tiếp tục hoạt động như mong đợi. Liên kết với các thuộc tính khác trên điều khiển Hộp kiểm, như IsEnabled, hoạt động bình thường. Nhưng ràng buộc IsChecked vẫn bị hỏng cho đến khi tôi làm mới trang.

Đây là XAML sử dụng cho một trong các điều khiển CheckBox tôi:

<CheckBox IsChecked="{Binding IncludeNote}" Content="Note" IsEnabled="{Binding IsBusy, Converter={StaticResource boolNot}}" /> 

Như bạn thấy, không có gì lạ mắt xảy ra ở đây là. Nhưng sau khi điều hướng ứng dụng WPF tiến lên hoặc lùi về phía trang, ràng buộc IsChecked sẽ bị hỏng trong khi thuộc tính IsEnabled sẽ tiếp tục hoạt động.

Điều gì đang xảy ra ở đây? Đây có phải là một lỗi?

CẬP NHẬT: Sau khi chơi xung quanh với một số lựa chọn thay thế, tôi phát hiện ra rằng vấn đề này cũng ảnh hưởng đến điều khiển ToggleButton, mà CheckBox xuất phát từ đó.

CẬP NHẬT 2: Và nó cũng bị hỏng cho thuộc tính TextBox.Text.

Có cách nào để "làm mới" các ràng buộc dữ liệu cho các điều khiển này không? Hoặc tôi có nên thực hiện một số cách tiếp cận khác để gỡ rối vấn đề này không?

Trả lời

5

Dường như, nó lỗi. Đây là báo cáo lỗi trên Microsoft Connect: Binding does not work after back/forward navigation.

Người dùng đã báo cáo lỗi, RQDQ, cũng đề cập đến cách tiếp cận của mình để đối phó với các vấn đề:

Cách giải quyết tôi đã tìm thấy là để tự gọi BindingOperations.SetBinding cho tất cả các ràng buộc trong trang trong Đã tải sự kiện. Điều này xuất hiện để làm việc cho dù điều hướng một cách rõ ràng hoặc thông qua lịch sử (trở lại/chuyển tiếp hoạt động).

Đây chỉ là vấn đề trong WPF4. Liên kết dữ liệu hoạt động như mong đợi trong .NET 3.5.

Tôi hy vọng Microsoft sẽ khắc phục sự cố này một cách nhanh chóng. Đây là một vấn đề nghiêm trọng đối với các ứng dụng WPF định hướng.

0

Cách giải quyết đơn giản là đặt KeepAlive thành true và sau đó để đảm bảo không có vấn đề với VIewModel có trạng thái xấu từ tải trang trước, DataContext được đặt thành một trường hợp mới mỗi lần trong sự kiện được tải (tức là không liên kết với một thể hiện của ViewModel trong từ điển Page.Resources của bạn ví dụ như nó sẽ được tiếp tục tồn tại).

Cách tiếp cận tiêu chuẩn mà chúng tôi sử dụng để ràng buộc trang với mô hình chế độ xem là một hành vi đơn giản được đính kèm với trang.

public sealed class PageViewModelBehavior : Behavior<Page> 
{ 
    public Type DataType { get; set; } 

    protected override void OnAttached() 
    { 
     this.AssociatedObject.KeepAlive = true; 
     this.AssociatedObject.Loaded += this.AssociatedObjectLoaded; 
     this.AssociatedObject.Unloaded += this.AssociatedObjectUnloaded; 
     base.OnAttached(); 
    } 

    protected override void OnDetaching() 
    { 
     this.AssociatedObject.Unloaded -= this.AssociatedObjectUnloaded; 
     this.AssociatedObject.Loaded -= this.AssociatedObjectLoaded; 
     base.OnDetaching(); 
    } 

    private void AssociatedObjectLoaded(object sender, RoutedEventArgs e) 
    { 
     if (this.DataType == null || !typeof(IPageViewModel).IsAssignableFrom(this.DataType)) 
     { 
      throw new InvalidOperationException("PageViewModelBehavior.DataType is not set. Page: " + this.AssociatedObject.GetType().Name); 
     } 

     this.AssociatedObject.DataContext = Activator.CreateInstance(this.DataType); 

     // TODO: Call load on your page view model etc. 
    } 


    private void AssociatedObjectUnloaded(object sender, RoutedEventArgs e) 
    { 
     // TODO: Call unload on your page view model etc. 

     // Allow the throw-away view model to be GC'd 
     this.AssociatedObject.DataContext = null; 
    } 
} 

Điều này đảm bảo trang bị ràng buộc lại mỗi lần người dùng điều hướng trở lại trang.Điều này cũng cho phép bạn sử dụng container IOC yêu thích của bạn để tạo ViewModel.

+0

Vấn đề lớn nhất ở đây là nó có thể nhanh chóng dẫn đến rò rỉ bộ nhớ. – ouflak

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