区分用户交互引发的事件与我自己的代码SelectedIndexChanged事件在我的应用程序中从组合框触发,具体情况如下:在组合框中,或在以下情况下:我自己的代码更新组合框的SelectedItem以反映组合框现在显示不同对象的属性。我对案例1的SelectedIndexChanged事件很感兴趣,这样我就可以更新当前对象的属性。但在情况2中,我不希望事件触发,因为对象的属性没有改变。一个例子可能会有所帮助。让我们考虑一下,我有一个包含人员列表的列表框,我有一个组合框代表列表中当前选定人员的国籍。如果当前在列表中选择了Fred,则可能会发生情况1,并且我使用组合框将他的国籍从英语更改为威尔士语。如果我在列表中选择ScottishBob,就会发生情况2。在这里,我的列表更新事件处理程序代码发现Bob现在已被选中,并更新组合框,以便Scots现在成为所选项目。这会导致组合框的SelectedIndexChanged事件被触发以将Bob的国籍设置为苏格兰,即使它已经是苏格兰了。如何在不触发SelectedIndexChanged事件的情况下更新组合框的SelectedItem属性?一种方法是注销事件处理程序,设置SelectedItem,然后重新注册事件处理程序,但这似乎很乏味且容易出错。一定会有更好的办法。我创建了一个名为SuspendLatch的类。欢迎提供更好的名称,但它可以满足您的需求,您可以像这样使用它:EventArgse){if(suspendLatch.HasOutstandingTokens){返回;}//做一些工作}它不是很漂亮,但它可以工作,并且与注销事件或布尔标志不同,它支持嵌套操作,有点像TransactionScope。您不断从闩锁中获取令牌,只有在处理完最后一个令牌时HasOutstandingTokens才会返回false。这很好,也很安全。虽然不是线路安全的……这是SuspendLatch的代码:publicclassSuspendLatch{privateIDictionarytokens=newDictionary();publicSuspendLatchTokenGetToken(){SuspendLatchTokentoken=newSuspendLatchToken(this);tokens.Add(token.Key,token);返回令牌;}publicboolHasOutstandingTokens{get{returntokens.Count>0;}}publicvoidCancelToken(SuspendLatchTokentoken){tokens.Remove(token.Key);}publicclassSuspendLatchToken:IDisposable{privatebooldisposed=false;私有Guid密钥=Guid.NewGuid();私有的SuspendLatch父母;内部SuspendLatchToken(SuspendLatchparent){this.parent=parent;}publicGuidKey{get{returnthis.key;}}publicoverrideboolEquals(objectobj){SuspendLatchTokenother=objasSuspendLatchToken;if(other!=null){returnKey.Equals(other.Key);}else{返回错误;}}publicoverrideintGetHashCode(){returnKey.GetHashCode();}publicoverridestringToString(){returnKey.ToStrinG();}publicvoidDispose(){Dispose(true);GC.SuppressFinalize(这个);}protectedvirtualvoidDispose(booldisposing){if(!disposed){if(disposing){//处置托管资源。parent.CancelToken(this);}//没有要释放的非托管资源,但是//如果我们添加它们,它们需要在这里释放。}处置=真;//如果可用,调用//基类的Dispose(Boolean)方法//base.Dispose(disposing);我认为最好的方法是使用标志变量:boolupdatingCheckbox=false;voidupdateCheckBox(){updatingCheckBox=true;checkbox.Checked=true;updatingCheckBox=false;}voidcheckbox_CheckedChanged(objectsender,EventArgse){if(!updatingCheckBox)PerformActions()}[编辑:刚刚发布了代码并且不是很清楚]在这种情况下,当通过updateCheckBox()更改复选框时,当复选框被选中时,事件处理程序将不会执行其正常操作我总是使用布尔标志变量来防止不需要的事件处理程序。TaskVision示例应用程序教我如何执行此操作。所有事件的事件处理程序代码如下所示:privateboollockEvents;protectedvoidMyEventHandler(objectsender,EventArgse){if(this.lockEvents){返回;}this.lockEvents=true;//处理你的事件。..this.lockEvents=false;我让事件发生。但是,我在更改索引之前设置了一个标志,然后将其翻转。在事件处理程序中,我检查是否设置了标志,如果是则退出处理程序。我认为你的重点应该放在对象上而不是发生的事件上。假设你有这个事件voidcombobox_Changed(objectsender,EventArgse){PerformActions()}并且PerformActions做了一些事情期望看到一些效果classPerson:IPerson{INationalityNationality{get{returnm_nationality;}set{if(m_nationalityvalue){m_nationality=value;this.IsDirty=true;}}}}这里的要点是的,让对象跟踪自身发生的事情,而不是UI。这还可以让您跟踪对象上的脏标记,这对以后的持久化很有用。这也使您的UI保持干净,并防止它出现可能容易出错的奇怪事件注册代码。我终于找到了避免事件被激活太多次的解决方案。我使用一个计数器,我只在不需要时挂钩/取消挂钩我想屏蔽的事件,当我再次需要它时。下面的示例演示如何隐藏数据网格的CellValueChanged事件。以上就是C#学习教程:区分用户交互引起的事件以及本人代码分享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注——EventMaskvalueChangedEventMask;//在类构造函数中valueChangedEventMask=newEventMask(()=>{dgv.CellValueChanged+=newDataGridViewCellEventHandler(dgv_CellValueChanged);},()=>{dgv.CellValueChanged-=newDataGridViewCellEventHandler(dgv_CellValueChangedide);使用}pushto)//H;事件并弹出以使其再次可用。该操作可以嵌套或在事件本身中使用。voidchangeCellOperation(){valueChangedEventMask.Push();...cell.Value=myNewCellValue...valueChangedEventMask.Pop();}//类publicclassEventMask{Actionhook;动作解钩;整数计数=0;publicEventMask(Actionhook,ActionunHook){this.hook=hook;this.unHook=unHook;}publicvoidPush(){count++;如果(计数==1)解钩();}publicvoidPop(){count--;如果(计数==0)挂钩();}}收集自网络,不代表立场,如涉及侵权,请点击右侧联系管理员删除,如需转载请注明出处:
