2015-04-06 47 views
0

當我將一個「後退按鈕」綁定到ReactiveUI中的路由器時,我的ViewModel不再被垃圾回收(我的視圖也一樣)。這是一個錯誤,還是這個我做一些愚蠢的事情?綁定ReactiveCommand可以防止ViewModel被垃圾回收

這裏是我的MeetingPageViewModel:

public class MeetingPageViewModel : ReactiveObject, IRoutableViewModel 
{ 
    public MeetingPageViewModel(IScreen hs, IMeetingRef mRef) 
    { 
     HostScreen = hs; 
    } 

    public IScreen HostScreen { get; private set; } 

    public string UrlPathSegment 
    { 
     get { return "/meeting"; } 
    } 
} 

這裏是我的MeetingPage.xaml.cs文件:

public sealed partial class MeetingPage : Page, IViewFor<MeetingPageViewModel> 
{ 
    public MeetingPage() 
    { 
     this.InitializeComponent(); 

     // ** Comment this out and both the View and VM will get garbage collected. 
     this.BindCommand(ViewModel, x => x.HostScreen.Router.NavigateBack, y => y.backButton); 

     // Test that goes back right away to make sure the Execute 
     // wasn't what was causing the problem. 
     this.Loaded += (s, a) => ViewModel.HostScreen.Router.NavigateBack.Execute(null); 
    } 

    public MeetingPageViewModel ViewModel 
    { 
     get { return (MeetingPageViewModel)GetValue(ViewModelProperty); } 
     set { SetValue(ViewModelProperty, value); } 
    } 
    public static readonly DependencyProperty ViewModelProperty = 
     DependencyProperty.Register("ViewModel", typeof(MeetingPageViewModel), typeof(MeetingPage), new PropertyMetadata(null)); 

    object IViewFor.ViewModel 
    { 
     get { return ViewModel; } 
     set { ViewModel = (MeetingPageViewModel)value; } 
    } 
} 

我再運行了,看到底是怎麼回事,我用VS 2013專業版,並打開內存分析器。我也(作爲一個測試)進行了所有世代的強制GC收集並等待終結者。當上面沒有註釋該行時,完成後,會有三個MeetingPage和MeetingPageViewModel實例。如果我刪除了BindCommand行,則沒有實例。

我的印象是這些會自行消失。問題是HostScreen對象還是引用比此VM更長的對象的路由器?那東西倒了?

如果是這樣,建議不要掛鉤後退按鈕?使用Splat和DI?非常感謝!

回答

0

繼續我最後的想法,我可以通過以下方式解決這個問題。在我App.xaml.cs,我一定要對的RoutingState申報依賴注入:與後退按鈕

 var r = new RoutingState(); 
     Locator.CurrentMutable.RegisterConstant(r, typeof(RoutingState)); 

然後,在每個視圖的構造函數(該.xaml.cs代碼)我的Windows商店應用,我不再使用上面的代碼,而是將其替換爲:

 var router = Locator.Current.GetService<RoutingState>(); 
     backButton.Click += (s, args) => router.NavigateBack.Execute(null); 

這樣做,我可以多次訪問該網頁,因爲我想以後決不做我看到留在分析儀的實例。

我會等待將此標記爲給真正的專家一些時間來建議另一個(更好的?)方法的答案。