問題闡述:使用MVVMLight導航發現導航後VM裡面的資料並未進行重置,需要介面跳轉後,歷史VM也進行銷燬重置,並釋放
解決辦法:
方法一:在當前介面進行Unloaded進行VM登出並進行重新注入程式碼如下
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<i:Interaction.Triggers> <i:EventTrigger EventName="Unloaded"> <i:InvokeCommandAction Command="{Binding UnloadedCommand}" /> </i:EventTrigger> </i:Interaction.Triggers>
private RelayCommand _UnloadedCommand; public RelayCommand UnloadedCommand => _UnloadedCommand ?? (_UnloadedCommand = new RelayCommand(ExecuteUnloadedCommand)); void ExecuteUnloadedCommand() { SimpleIoc.Default.Unregister<MainWindowViewModel>(); SimpleIoc.Default.Register<MainWindowViewModel>(); }
方法二:對當前的VM獲取方式進行做文章
處理思想:當介面在進行獲取當前VM的時候建立新的VM就可以了
處理邏輯:封裝一個方法,獲取當前已經註冊的VM然後進行封裝轉化建立出新的VM,建立過程中並將目標已有多個引數的構造引數進行二次轉化封裝
/// <summary> /// 建立並轉化新的VM不再使用原有已經註冊的建構函式 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> private T CreateVM<T>() { var newClass = SimpleIoc.Default.GetInstance<T>(); Type type = newClass.GetType(); ConstructorInfo[] constructors = type.GetConstructors(); var Parameters = constructors[0].GetParameters(); object[] args = new object[Parameters.Length]; for (int i = 0; i < Parameters.Length; i++) { var data = SimpleIoc.Default.GetAllInstances(Parameters[i].ParameterType).FirstOrDefault(); args[i] = data; } var vm = constructors[0].Invoke(args); return (T)vm; }
使用方法:原有的VM呼叫的方式為
現在替換為
替換完成後其他的正常使用
注意:使用的第二種方式的話,SimpleIoc.Default.GetInstance方法設定其他介面的VM將失效,選擇使用,推薦第二種方式,這樣做到了完全解耦,介面跳轉VM進行銷燬,新頁面產生,新的VM也將進行產生