2017-01-19 40 views
2

我会尽可能详细地解释我的问题。我的应用程序使用mvvm编写,并有一个加载一些静态视图的shellview。继承人问题1: 在shellviewmodel中实例化这些视图模型是否是一种很好的做法?ReactiveUI Viewinjection。如何做到这一点

public ShellViewModel(IScreen screen) 
    { 
     HostScreen = screen; 


     LogoViewModel = new LogoViewModel(HostScreen); 
     ... 
     StatusViewModel = new StatusViewModel(); 

    } 

反正我也有有一个列表,它的ItemSource属性当用户选择了一个新的列表项被绑定到一个ReactiveList现在

 public ShiftOrderView()//ShiftOrderViewModel viewModel) 
      { 
       InitializeComponent(); 

       this.WhenActivated(
        d => 
         { 
          this.OneWayBind(ViewModel, vm => vm.ProductionOrderList, v => v.ShiftOrder.ItemsSource).AddTo(d); 
    }); 
} 

这个项目显示在另一个视图静态视图。我目前通过导航做到这一点

 this.WhenActivated(d => 
     { 
      this.WhenAnyObservable(o => o.ProductionOrderList.ItemChanged) 
       .Where(x => x.PropertyName == "ItemsLeft") 
       .Select(x => x.Sender) 
       .Where(x => x.ItemsLeft == 0) 
       .Subscribe(x => 
       { 

        ProductionOrderList.Remove(x); 
       }).AddTo(d); 

      this.WhenAnyValue(vm => vm.SelectedProductionOrderViewModel).Where(pvm => pvm != null) 
       .Subscribe(pvm => 
       { 
        HostScreen.Router.NavigateAndReset.Execute(
         new ProductionOrderDetailViewModel(HostScreen, 
         Locator.CurrentMutable.GetService<IProductionItemService>(), pvm)); 
       }).AddTo(d); 

     }); 

但我认为这是不正确的方式,并引入了内存泄漏。正如你在上面的代码中看到的,当itemsleft属性达到0时,项目从列表中移除。但是我不知道如何正确处理这些项目。如果我在导航方法中创建新实例,旧的新ProductionOrderDetailViewModel会被丢弃吗?如果不是我怎么能做到这一点? 我相信我错过了一些正确答案所需的部分,所以请问,我会提供您需要的信息。

在此先感谢和亲切的问候

+0

我有一种感觉,你在这里使用了错误的单词。 '当itemsleft属性达到0时,项目从列表中移除。你的意思是''当发送者的itemsleft属性达到0时,发件人会从列表中删除 – bradgonesurfing

回答

0

我想我看到你有问题模式,我承认它。你有一个T : IDisposable类型的财产,当该财产更新时,你希望处置旧版本。我有一个IObservable<T>的扩展方法,它将以一般方式解决这类问题。

扩展方法是

public static IDisposable SubscribeDisposable<T> 
     (this IObservable<T> observable, Func<T, IDisposable> action) 
    { 
     var d = new SerialDisposable(); 
     return observable 
      .Finally(() => d.Dispose()) 
      .Subscribe(e => 
      { 
       d.Disposable = Disposable.Empty; 
       d.Disposable = action(e); 
      }); 
    } 

,您可以使用它像

this 
    .WhenAnyValue(p=>p.DisposableProperty) 
    .SubscribeDisposable(v=>v) 
    .AddTo(d); 

但通常我把更复杂的东西在SubscribeDisposable。例如,在我的一些代码,我有

this.LoadUnloadHandler(() => this 
       .WhenAnyValue(p => p.ViewModel) 
       .WhereNotNull() 
       .SubscribeDisposable(x=>x.StartAnimation())); 

每当我的视图模型的变化,我需要停止旧的动画,并开始一个新的。最简单的方法是StartAnimation()返回停止动画的IDisposableSubscribeDisposable确保在创建新的IDisposable之前处理旧的IDisposable,从而使动画排列整齐。

只是为了清楚StartAnimation方法。

public IDisposable StartAnimation() { 
    return Animation = new PlayController(
     maximum: 2 * Math.PI, 
     minSpeed: Math.PI/180 * 10, 
     maxSpeed: 2 * Math.PI, 
     currentSpeed: Math.PI, 
     jogAmount: Math.PI/50, 
     fps: 120, 
     modes: new Dictionary<AnimationMode, string> 
     { 
      { AnimationMode.PlayOnce, "Play once" }, 
      { AnimationMode.PlayAndReverse, "Play and reverse" }, 
      { AnimationMode.Loop, "Loop" } 
     }) { StickyWidth = 50 }; 
} 

我希望这是你在找什么。