代码之家  ›  专栏  ›  技术社区  ›  Dan Vinton

从长期事件源取消订阅窗体组件-何时?

  •  0
  • Dan Vinton  · 技术社区  · 14 年前

    interface ITranslationProvider 
    {
        string GetTranslation(string key);
        event LanguageChangedEvent LanguageChanged;
    }
    

    ie:语言在运行时可以更改,组件需要通过更新显示字符串来响应。

    什么时候是退订的正确时间 LanguageChanged 事件?

    例如,它似乎覆盖了 Disposing() 应该工作:

    class MyPanel : System.Windows.Forms.Panel 
    {
        public MyPanel(ITranslationProvider translator) 
        {
            this.translator = translator;
            translator.LanguageChanged += new LanguageChangedEvent(SetText);
            SetText();
        }
    
        protected override void Dispose(bool disposing) 
        {
            base.Dispose(disposing);
    
            // is this the correct place to unregister? will Dispose() get 
            // called on this panel, even though the translator's event has 
            // a reference to it?
            translator.LanguageChanged -= new LanguageChangedEvent(SetText);
        }
    
        private void SetText() 
        {
            this.Text = translator.GetTranslation("my.panel.text");
        }
    
        private ITranslationProvider translator;
    }
    

    3 回复  |  直到 14 年前
        1
  •  2
  •   SLaks    14 年前

    你的控制将是 Dispose 当父窗体被释放时。

    Show() ,.Net将在关闭时自动处理它。
    如果你打电话 ShowDialog() ,您负责处理表单,可能是在 using 阻止(在任何情况下都应该处理窗体,即使它没有添加事件处理程序)

        2
  •  1
  •   Hans Passant    14 年前

    是的,使用Disposing()可以。如果客户机代码弄乱了这一点,所以它不会被调用,那么它就有更大的问题,因为句柄泄漏。

    请注意,这种“反向事件”很尴尬。如果您知道事件源总是存在于使用者之外,那么回调可以是更合适的解决方案。接口声明示例:

    public interface ITranslatableControl {
        void SetText();
    }
    
    public MyPanel : Panel, ITranslatableControl {
        public MyPanel() {
           TranslationManager.RegisterControl(this);
        }
        void SetText() {
           this.Text = TranslationManager.GetText(this, "mumble");
        }
    }
    
    public static class TranslationManager {
        private List<ITranslatableControl> controls;
        public void RegisterControl(ITranslatableControl text) {
           Control ctl = (Control)text;
           ctl.Disposed += delegate { controls.Remove(text); }
           controls.Add(text);
           text.SetText();    // optional
        }
    }
    

        3
  •  0
  •   Tergiver    14 年前