C#学习教程:从序列化ViewModel恢复时ComboxSelectedItem不适用奇怪的问题。软件的思路是——当窗口关闭时——将当前的Viewmodel状态保存在一个json文件中。在下次启动时,应用程序只提供json。现在我的问题是当使用json文件恢复它时,包含自定义类型列表的组合框,组合框有值但没有SelectedItem。创建ViewModel实例并使用默认值初始化公共属性时(通过代码隐藏执行此操作),一切都很好。以下是一些代号显示“错误”的代号:使用系统查看代号背后;使用System.Windows;使用System.IO;使用Newtonsoft.Json;namespaceCrazyWpf{publicpartialclassMainWindow:Window{privateDemoViewModeldvm;publicMainWindow(){InitializeComponent();this.dvm=(DemoViewModel)this.rootElement.DataContext;}privatevoidWindow_Closing(objectsender,System.ComponentModel.CancelEventArgse){stringfilePath=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),"settings.json");如果(File.Exists(filePath))File.Delete(filePath);File.WriteAllText(filePath,JsonConvert.SerializeObject(this.dvm,Formatting.Indented));}privatevoidWindow_Loaded(objectsender,RoutedEventArgse){stringfilePath=System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),"settings.json");如果(!File.Exists(filePath)){this.SetDefaultSettings();返回;}DemoViewModeld=JsonConvert.DeserializeObj等(文件。ReadAllText(文件路径));this.dvm.ID=d.ID;this.dvm.Name=d.Name;this.dvm.StatusType=d.StatusType;}}}BaseViewModel:使用System.ComponentModel;命名空间CrazyWpf{公共抽象类BaseViewModel:INotifyPropertyChanged{公共事件PropertyChangedEventHandlerPropertyChanged;protectedvoidOnPropertyChanged(stringpropertyName){if(this.PropertyChanged!=null)this.PropertyChanged(this,newPropertyChangedEventArgs(propertyName));}}}视图模型usingSystem;使用System.Collections.Generic;使用System.Linq;使用Newtonsoft.Json;命名空间CrazyWpf{classDemoViewModel:BaseViewModel{[JsonIgnore]privateintid;[JsonProperty(Order=1)]publicintID{get{returnthis.id;}set{if(this.id!=value){this.id=value;this.OnPropertyChanged("ID");}}}[JsonIgnore]私有字符串名称;[JsonProperty(Order=2)]publicstringName{get{returnthis.name;}set{if(this.name!=value&&value!=null){this.name=value;this.OnPropertyChanged("名称");}}}[JsonIgnore]privateStatusTyp状态类型;[JsonProperty(Order=3)]publicStatusTypStatusType{get{returnthis.statusType;}set{if(this.statusType!=value&&value!=null){this.statusType=value;this.OnPropertyChanged("StatusType");}}}[JsonIgnore]私有列表statusTypeList;[JsonProperty(Order=4)]publicListStatusTypeList{get{returnthis.statusTypeList;}set{if(this.statusTypeList!=value&&value!=null){this.statusTypeList=value;this.OnPropertyChanged("StatusTypeList");}}}publicDemoViewModel(){this.StatusTypeList=newFunc(()=>{varlist=Enum.GetValues(typeof(Status)).Cast().ToDictionary(k=>(int)k,v=>v.ToString()).Select(e=>newStatusTyp(){Value=e.Key,Name=e.Value,Status=Enum.GetValues(typeof(Status)).Cast().Where(x=>{return(int)x==e.Key;}).FirstOrDefault()}).ToList();返回列表;})();}}publicclassStatusTyp{publicintValue{get;放;}公共字符串名称{得到;放;}公共状态状态{得到;放;}}publicenumStatus{NotDetermined=0,Determined=1,Undetermined=2,Unknown=3}}如果你有一个ItemsSource和一个SelectedItem,那么SelectedItem中的实例必须在绑定到ItemsSource的集合中,如果没有,那么您的绑定将无法按预期工作。该控件使用引用相等性来确定ItemsSource中的哪个项目是SelectedItem中的项目并更新UI。这通常不是问题,因为控件会为您填充SelectedItem,但如果您从ViewModel端进行更新,则必须确保正确管理您的引用。这在序列化/反序列化视图模型时可能是个问题。大多数常见的序列化程序不跟踪引用,因此它们无法在反序列化时恢复。同一个对象可以在原始对象图中的多个位置引用,但在反序列化之后,您现在有多个原始对象的实例分布在整个再水合图中。这不符合您的要求。你需要做的是,反序列化后,在集合中找到匹配的实例,并替换为SelectedItem中的实例。或者,使用跟踪实例的序列化程序。.XAML序列化程序已经做到了这一点,它是一个非常好的.net对象图xml序列化程序。以上是C#学习教程:从序列化的ViewModel中恢复时,ComboxSelectedItem不适用于所有分享的内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收集,不代表作品如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
