【问题标题】:How to detect C# control name changed?如何检测 C# 控件名称更改?
【发布时间】:2016-04-25 22:54:03
【问题描述】:

我使用 C# Windows 窗体控件库创建了一个复合控件,当我在测试程序中使用新控件时,我想找到一种方法来检测新控件的名称在设计时何时更改,我该怎么办?

【问题讨论】:

  • 你说的是基于 UserControl 的复合控件吗?您想对 UserControl 的 Name 属性做出反应吗?
  • 是的,我想在设计时检测它

标签: c# controls composite-controls


【解决方案1】:

没有事件“OnNameChanged”并且名称属性本身不是虚拟的,因此不可覆盖......恐怕没有确定的方法......

一些建议:

  • 使用“new”定义您自己的 Name-Property,但继承的类不会自动超越它,更糟糕的是,强制转换为 Control 和使用 Control.Name 只会围绕您的属性工作...

  • 定义一个虚拟的“MyName”-Property,并仅使用它来写入控件的 Name-Property。仍然会调用 Control.Name,但至少您可以强制使用 MyName...

  • 在您的构造函数中添加名称并定义一个计时器,以便在发生更改时定期查看

总的来说,我必须承认,我不会使用其中任何一个...我不知道您到底想要实现什么,但我会尝试找到一种不同的方法来实现这个目标...

【讨论】:

    【解决方案2】:
    public MyControl : UserControl
    {
         public new string Name 
         {
             get  { return base.Name; }
    
             set  
             {
                base.Name = value;
    
                // handle the name change here....
             }
        }
    
    }
    

    【讨论】:

    • 那行不通。如果您调用 ((UserControl)myControl).Name = "...",则只会调用基本属性。
    【解决方案3】:

    您可以像在此示例中一样使用IComponentChangeService(在System.ComponentModel.Design):

    public class MyControl : UserControl
    {
        public event EventHandler NameChanged;
        protected virtual void OnNameChanged()
        {
            EventHandler handler = NameChanged;
            if (handler != null) handler(this, EventArgs.Empty);
        }
    
        protected override void OnCreateControl()
        {
            base.OnCreateControl();
    
            IComponentChangeService changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
            if (changeService == null) return; // not provided at runtime, only design mode
    
            changeService.ComponentChanged -= OnComponentChanged; // to avoid multiple subscriptions
            changeService.ComponentChanged += OnComponentChanged;
        }
    
        private void OnComponentChanged(object sender, ComponentChangedEventArgs e)
        {
            if (e.Component == this && e.Member.Name == "Name")
                OnNameChanged();            
        }
    }
    

    此服务仅在设计模式下提供,不在运行时提供。
    我取消订阅并再次订阅ComponentChanged 事件(以避免多次订阅)。

    在事件处理程序OnComponentChanged 中,我检查我的名字是否已更改并引发NameChanged 事件。

    【讨论】:

    • 您提供的代码非常有用,但我遇到了另一个问题。如何获取我在属性窗口中输入的名称?我使用this.Name 来获取名称,但我得到的是“MyControl”而不是我在属性窗口中输入的单词
    • @TwenteMaster this.Name 实际上对我来说很好用(只要 this 确实是正确的实例,请检查)。我想我需要查看更多代码,但听起来这更像是一个新问题。
    • 我忘了告诉你更多信息,在我的代码中,MyControl 继承自UserControl,而不是Control,这是问题所在吗?如果是,我该怎么办?我不想改变继承关系
    • @TwenteMaster 没有区别,它也适用于UserControl。我在OnNameChanged 中使用MessageBox.Show(this.Name) 进行了尝试,当我在设计器中设置(Name) 属性时,它显示MessageBox 具有正确的更改值。
    • 我找到原因了,是其他代码改名了,我已经解决了。非常感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多