Determiningthecallerinasetter–orsilentlysettingaproperty给定标准视图模型实现,当一个属性改变时,有没有办法确定变革的始作俑者?换句话说,在下面的视图模型中,我希望“PropertyChanged”事件的“sender”参数是调用Prop1setter的实际对象:}设置{如果(_prop1==值)返回;_prop1=价值;//在这里,我可以确定发件人吗?RaisePropertyChanged(propertyName:"Prop1",sender:this);}}私有双_prop1;//TODOimplementINotifyPropertyChanged}或者,我可以将CallerMemberNameAttribute应用于属性设置器吗?如果我理解正确的话,你问的是二传手的来电者。这意味着,之前的方法在进入setter本身之前调用了调用堆栈(这也是一种方法)。为此使用StackTrace.GetFrames方法。例如(取自http://www.csharp-examples.net/reflection-callstack/):使用System.Diagnostics;[STAThread]publicstaticvoidMain(){StackTracestackTrace=newStackTrace();//获取调用堆栈StackFrame[]stackFrames=stackTrace.GetFrames();//获取方法调用(帧)//写入调用堆栈方法名称foreach(StackFramestackFrameinstackFrames){Console.WriteLine(stackFrame.GetMethod().Name);//writemethodname}}Output:MainnExecuteAssemblyExecuteAssemblyRunUsersAssemblyThreadStart_ContextRunThreadStart基本上,你想要的是stackFrames[1].GetMethod().Name。我对这个问题的第一个解决方案是派生自PropertyEventArgs。除了PropertyName之外,新类还有一个名为PropertyChangeOrigin的成员。当您调用RaisePropertyChanged时,您将根据从CallerMemberName属性收集的信息提供由PropertyChangeOrigin设置的新类的实例。现在,当您订阅该事件时,订阅者可以尝试将事件参数传递给您的新类,并在转换成功时使用该信息。您看过CallerMemberNamemsdn页面了吗?我用它来避免做RaisePropertyChanged("some_name_here");通过在基类中使用它,所有属性都只调用RaisePropertyChanged();。我相信它也可以用在setter中......编辑:根据评论的问题,这里有一些代码可以做到这一点(愚蠢,但仍然会解决这个问题:)publicintsome_int{get{return_someInt;}设置{_someInt=值;varv=check_sender();Console.Out.WriteLine("在{0}的setter中",v);}}私有int_someInt;privatestringcheck_sender([CallerMemberName]stringproperty=""){返回属性;然后,如果在setter中,我会写:some_int=7;//显然,任何数字都会导致它触发,你会进入输出(注意中间的一行,添加其余部分,这样你就会看到它是一些控制台输出):'WPFMVVMforSO.vshost.exe'(托管(v4.0.30319):已加载“C:WindowsMicrosoft.NetassemblyGAC_MSILPresentationFramework-SystemXmlLinqv4.0_4.0.0.0__b77a5c561934e089PresentationFramework-SystemXmlModulembollinq.dll”,已优化跳过加载并启用调试器选项“仅我的代码”。在some_int'WPFMVVMforSO.vshost.exe'(Managed(v4.0.30319))的设置器中:加载'C:WindowsMicrosoft.NetassemblyGAC_MSILPresentationFramework.Aerov4.0_4。0.0.0__31bf3856ad364e35PresentationFramework.Aero.dll',跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。这是我一直用作INotifyPropertyChanged和我的视图模型之间的中间点:公共事件PropertyChangedEventHandlerPropertyChanged=delegate{};publicvoidOnPropertyChanged([CallerMemberName]stringproperty=""){if(_arguments==null){_arguments=newDictionary();}if(!_arguments.ContainsKey(property)){_arguments.Add(property,newPropertyChangedEventArgs(property));}PropertyChanged(这个,_arguments[属性]);这里有两件事它使用[CallerMemberName]属性设置属性名称。使用语法如下:publicstringWords{set{if(value!=_words){_words=value;OnPropertyChanged();另外,它将PropertyChangedEventArgs对象存储在一个字典中,所以对于经常设置的属性,不会创建多次。我相信这可以解决您的问题。祝你好运!每当我必须向VM传递额外信息时,我都使用命令取得了巨大的成功:Commands、RelayCommands和EventToCommand对大家有用,需要了解更多的C#学习教程。希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
