一個偶爾出現令人不爽的WPF界面顯示問題:“未將對象引用設置到對象的實例”。 ...
在做即時通信項目中,使用WPF的MVVM模式,如果在前臺綁定VM,經常會顯示波浪線,滑鼠放上去提示未將對象引用設置到對象的實例,但程式能正常運行,後來發現如果前臺不綁定VM,在後臺cs里綁定就不會出現此問題。雖然不是大問題,但對於強迫症患者還是很難受的。
<UserControl.DataContext> <vm:AlarmGroupListVM/> </UserControl.DataContext>
沒有必要非得改,因為顯示波浪線這個有時候出現有時候不出現,而且改了,對於純粹的MVVM模式忠實者會嗤之以鼻。
另外,因為某個頁面初次載入時需要顯示全部的用戶數據,耗時較長,為了客戶友好性,在初始載入的方法中使用了非同步線程載入,界面會先顯示出來,然後就出現了一個比較難受的問題,程式能正常運行,但是前臺界面的設計中顯示報錯了,提示未將對象引用設置到對象的實例,並詳細的指出了問題就出在初始載入的方法中,看不到界面非常難受,必須解決這個問題,上網查找相關問題,定位到問題出現的原因。
分析原因:
VS會自動的預編譯程式,會按照程式在啟動時的需要解釋xaml,按照xaml中的順序生成控制項,先佈局的先生成。在初始載入方法中啟動非同步線程,非同步線程中使用前臺控制項綁定的屬性,與主UI線程分屬不同線程,VS判定不了先後順序,會認為你使用的屬性尚未實例,前臺中會顯示錯誤,正常啟動程式時則不會出現問題。
解決辦法:
在VM中的初始載入方法中添加限制,判斷當界面初始化完畢後在執行,可以使用if (this.IsLoaded)判斷,也可以直接改變初始載入的事件為Loaded。
1 <i:Interaction.Triggers> 2 <i:EventTrigger EventName="Loaded"> 3 <i:InvokeCommandAction Command="{Binding LoadDataCommand}"></i:InvokeCommandAction> 4 </i:EventTrigger> 5 <i:EventTrigger EventName="Closed"> 6 <i:InvokeCommandAction Command="{Binding CancelCommand}" CommandParameter="{Binding ElementName=groupCreate}"></i:InvokeCommandAction> 7 </i:EventTrigger> 8 </i:Interaction.Triggers>
界面恢復正常。