c# – 区分用户交互引发的事件和我自己的代码

前端之家收集整理的这篇文章主要介绍了c# – 区分用户交互引发的事件和我自己的代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
SelectedIndexChanged事件从我的应用程序从组合框中触发:

>用户选择不同的
组合框中的项目,或何时:
>我自己的代码更新组合
Box的SelectedItem反映出来
组合框现在正在显示
属性为不同的对象.

我对case1的SelectedIndexChanged事件感兴趣,所以我可以更新当前对象的属性.但是在第二种情况下,我不希望事件触发,因为对象的属性没有改变.

一个例子可能有帮助.让我们考虑一下我有一个列表框,其中包含一个人的列表,我有一个组合框,表示当前选定的人在列表中的国籍.如果Fred当前被列入名单,我可以使用案例1,而且我使用组合框将其国籍从英语改为威尔士语.如果我在列表中选择苏格兰的鲍勃,案例2就可能发生.在这里,我的列表更新事件处理程序代码看到Bob现在被选中,并更新组合框,以便苏格兰现在是选定的项目.这导致组合框的SelectedIndexChanged事件被触发,以将Bob的国籍设置为苏格兰,即使它已经是苏格兰人.

如何更新我的组合框的SelectedItem属性,而不会导致SelectedIndexChanged事件触发?一种方法是取消注册事件处理程序,设置SelectedItem,然后重新注册事件处理程序,但这似乎很乏味且容易出错.必须有更好的方法.

解决方法

我创建了一个我称为SuspendLatch的类.欢迎提供更好的名称,但它可以满足您的需要,您可以使用它:
void Method()
{
    using (suspendLatch.GetToken())
    {
        // Update selected index etc
    }
}

void listBox1_SelectedIndexChanged(object sender,EventArgs e)
{
    if (suspendLatch.HasOutstandingTokens)
    {
        return;
    }

    // Do some work
}

它不漂亮,但它的工作,不像注销事件或布尔标志,它支持嵌套操作有点像TransactionScope.你会从锁存器中继续使用令牌,只有当最后一个令牌被放置为HasOutstandingTokens返回false时才会使用令牌.尼斯和安全不是线程安全,但…

以下是SuspendLatch的代码

public class SuspendLatch
{
    private IDictionary<Guid,SuspendLatchToken> tokens = new Dictionary<Guid,SuspendLatchToken>();

    public SuspendLatchToken GetToken()
    {
        SuspendLatchToken token = new SuspendLatchToken(this);
        tokens.Add(token.Key,token);
        return token;
    }

    public bool HasOutstandingTokens
    {
        get { return tokens.Count > 0; }
    }

    public void CancelToken(SuspendLatchToken token)
    {
        tokens.Remove(token.Key);
    }

    public class SuspendLatchToken : IDisposable
    {
        private bool disposed = false;
        private Guid key = Guid.NewGuid();
        private SuspendLatch parent;

        internal SuspendLatchToken(SuspendLatch parent)
        {
            this.parent = parent;
        }

        public Guid Key
        {
            get { return this.key; }
        }

        public override bool Equals(object obj)
        {
            SuspendLatchToken other = obj as SuspendLatchToken;

            if (other != null)
            {
                return Key.Equals(other.Key);
            }
            else
            {
                return false;
            }
        }

        public override int GetHashCode()
        {
            return Key.GetHashCode();
        }

        public override string ToString()
        {
            return Key.ToString();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // Dispose managed resources.
                    parent.CancelToken(this);
                }

                // There are no unmanaged resources to release,but
                // if we add them,they need to be released here.
            }
            disposed = true;

            // If it is available,make the call to the
            // base class's Dispose(Boolean) method
            //base.Dispose(disposing);
        }
    }
}

猜你在找的C#相关文章