Classa dziedzicząca z toolTipa a jej zastosowanie

0

Być może powinno to wylądować w newbie, bo przyznam śmierdzi mi tu brakiem wiedzy z mojej strony. Do rzeczy:

Natknąlem się na ciekawe rozwiązanie związane z wyświetlaniem notyfikacji przy zablokowanych kontrolkach:
https://www.codeproject.com/articles/32083/displaying-a-tooltip-when-the-mouse-hovers-over-a

Kod w wersji c# jest tam w komentarzach, ale przekleje go tutaj. Sklada się z dwoch klas:

TransparentSheet.cs

using System.Security.Permissions;
using System.Windows.Forms;

namespace EnhancedToolTip
{
    public class TransparentSheet : ContainerControl
    {
        public TransparentSheet()
        {
            // Disable painting the background.
            this.SetStyle(ControlStyles.Opaque, true);
            this.UpdateStyles();

            // Make sure to set the AutoScaleMode property to None 
            // so that the location and size property don't automatically change 
            // when placed in a form that has different font than this.
            this.AutoScaleMode = AutoScaleMode.None;

            // Tab stop on a transparent sheet makes no sense.
            this.TabStop = false;
        }

        private const short WS_EX_TRANSPARENT = 0x20;

        protected override CreateParams CreateParams
        {
            [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
            get
            {
                CreateParams l_cp;
                l_cp = base.CreateParams;
                l_cp.ExStyle = (l_cp.ExStyle | WS_EX_TRANSPARENT);
                return l_cp;
            }
        }
    }
} 

EnhancedToolTip.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;

namespace EnhancedToolTip
{
    [ProvideProperty("ToolTipWhenDisabled", typeof(Control)),
    ProvideProperty("SizeOfToolTipWhenDisabled", typeof(Control))]    
    /// <summary>
    /// EnhancedToolTip supports the ToolTipWhenDisabled and SizeOfToolTipWhenDisabled
    /// extender properties that can be used to show tooltip messages when the associated
    /// control is disabled.
    /// </summary>
    public class EnhancedToolTip : ToolTip
    {
    #region ========== Required constructor ==========
        // This constructor is required for the Windows Forms Designer to instantiate
        // an object of this class with New(Me.components).
        // To verify this, just remove this constructor. Build it and then put the
        // component on a form. Take a look at the Designer.vb file for InitializeComponents(),
        // and search for the line where it instantiates this class.
        public EnhancedToolTip(IContainer p_container) : base()
        {
            // Required for Windows.Forms Class Composition Designer support
            if (p_container != null)
            {
                p_container.Add(this);
            }

            // Suscribes to Popup event listener
            // Comment out following lines if you are okay with the same Title/Icon for disabled controls.
            this.m_EvtPopup = new PopupEventHandler(EnhancedToolTip_Popup);
            this.Popup += this.m_EvtPopup;
        }
    #endregion

    #region ========== ToolTipWhenDisabled extender property support ==========
        private Dictionary<Control, string> m_ToolTipWhenDisabled = new Dictionary<Control, string>();
        private Dictionary<Control, TransparentSheet> m_TransparentSheet = new Dictionary<Control, TransparentSheet>();
        private Dictionary<Control, PaintEventHandler> m_EvtControlPaint = new Dictionary<Control, PaintEventHandler>();
        private Dictionary<Control, EventHandler> m_EvtControlEnabledChanged = new Dictionary<Control, EventHandler>();

        public void SetToolTipWhenDisabled(Control p_control, string value)
        {
            if (p_control == null)
            {
                throw new ArgumentNullException("control");
            }

            if (!String.IsNullOrEmpty(value))
            {
                this.m_ToolTipWhenDisabled[p_control] = value;
                if (!p_control.Enabled)
                {
                    // When the control is disabled at design time, the EnabledChanged
                    // event won't fire. So, on the first Paint event, we should call
                    // PutOnTransparentSheet().
                    m_EvtControlPaint.Add(p_control, new PaintEventHandler(control_Paint));
                    p_control.Paint += m_EvtControlPaint[p_control];
                }
                m_EvtControlEnabledChanged.Add(p_control, new EventHandler(control_EnabledChanged));
                p_control.EnabledChanged += m_EvtControlEnabledChanged[p_control];             
            }
            else
            {
                m_ToolTipWhenDisabled.Remove(p_control);
                if (m_EvtControlEnabledChanged != null)
                {
                    p_control.EnabledChanged -= m_EvtControlEnabledChanged[p_control];
                }
            }
        }

        private void control_Paint(object sender, PaintEventArgs e)
        {
            Control l_control;

            l_control = (Control)sender;
            this.PutOnTransparentSheet(l_control);
            // Immediately remove the handler because we don't need it any longer.
            if (m_EvtControlPaint != null)
            {
                l_control.Paint -= m_EvtControlPaint[l_control];
            }
        }
        
        private void control_EnabledChanged(object sender, EventArgs e)
        {
            Control l_control;

            l_control = (Control)sender;
            if (l_control.Enabled)
            {
                this.TakeOffTransparentSheet(l_control);
            }
            else
            {
                this.PutOnTransparentSheet(l_control);
            }
        }

        [Category("Misc"),
        Description("Determines the ToolTip shown when the mouse hovers over the disabled control."),
        Localizable(true),
        Editor(typeof(MultilineStringEditor), typeof(UITypeEditor)),
        DefaultValue("")]
        public string GetToolTipWhenDisabled(Control p_control)
        {
            if (p_control == null)
            {
                throw new ArgumentNullException("control");
            }

            if (m_ToolTipWhenDisabled.ContainsKey(p_control))
            {
                return m_ToolTipWhenDisabled[p_control];
            }
            else
            {
                return String.Empty;
            }
        }

        private void PutOnTransparentSheet(Control p_control)
        {
            TransparentSheet l_ts;

            l_ts = new TransparentSheet();
            l_ts.Location = p_control.Location;
            if (m_SizeOfToolTipWhenDisabled.ContainsKey(p_control))
            {
                l_ts.Size = this.m_SizeOfToolTipWhenDisabled[p_control];
            }
            else
            {
                l_ts.Size = p_control.Size;
            }
            p_control.Parent.Controls.Add(l_ts);
            l_ts.BringToFront();
            this.m_TransparentSheet[p_control] = l_ts;
            this.SetToolTip(l_ts, m_ToolTipWhenDisabled[p_control]);
        }

        private void TakeOffTransparentSheet(Control p_control)
        {
            TransparentSheet l_ts;
            
            if (m_TransparentSheet.ContainsKey(p_control))
            {
                l_ts = m_TransparentSheet[p_control];
                p_control.Parent.Controls.Remove(l_ts);
                this.SetToolTip(l_ts, String.Empty);
                l_ts.Dispose();
                m_TransparentSheet.Remove(p_control);
            }
        }
    #endregion

    #region ========== Support for the oversized transparent sheet to cover multiple visual controls. ==========
        private Dictionary<Control, Size> m_SizeOfToolTipWhenDisabled = new Dictionary<Control, Size>();

        public void SetSizeOfToolTipWhenDisabled(Control p_control, Size value)
        {
            if (p_control == null)
            {
                throw new ArgumentNullException("control");
            }

            if (!value.IsEmpty)
            {
                m_SizeOfToolTipWhenDisabled[p_control] = value;
            }
            else
            {
                m_SizeOfToolTipWhenDisabled.Remove(p_control);
            }
        }

        [Category("Misc"),
        Description("Determines the size of the ToolTip when the control is disabled." + 
                     " Leave it to 0,0, unless you want the ToolTip to pop up over wider" + 
                     " rectangular area than this control."),
        DefaultValue(typeof(Size), "0,0")]
        public Size GetSizeOfToolTipWhenDisabled(Control p_control)
        {
            if (p_control == null)
            {
                throw new ArgumentNullException("control");
            }

            if (m_SizeOfToolTipWhenDisabled.ContainsKey(p_control))
            {
                return m_SizeOfToolTipWhenDisabled[p_control];
            }
            else
            {
                return Size.Empty;
            }
        }
    #endregion

    #region ========== Comment out this region if you are okay with the same Title/Icon for disabled controls. ==========
        private PopupEventHandler m_EvtPopup;
        
        private string m_strToolTipTitle;
        /// <summary>
        /// ToolTip title when control is disabled
        /// </summary>
        public new string ToolTipTitle
        {
            get
            {
                return base.ToolTipTitle;
            }
            set
            {
                base.ToolTipTitle = value;
                this.m_strToolTipTitle = value;
            }
        }

        private ToolTipIcon m_ToolTipIcon;
        /// <summary>
        /// ToolTip icon when control is disabled
        /// </summary>
        public new ToolTipIcon ToolTipIcon
        {
            get
            {
                return base.ToolTipIcon;
            }
            set
            {
                base.ToolTipIcon = value;
                this.m_ToolTipIcon = value;
            }
        }

        private void EnhancedToolTip_Popup(object sender, PopupEventArgs e)
        {
            if (e.AssociatedControl is TransparentSheet)
            {
                base.ToolTipTitle = String.Empty;
                base.ToolTipIcon = ToolTipIcon.None;
            }
            else
            {
                base.ToolTipTitle = this.m_strToolTipTitle;
                base.ToolTipIcon = this.m_ToolTipIcon;
            }
        }

        protected override void Dispose(bool disposing)
        {
            // Removing Popup Handler.
            if (this.m_EvtPopup != null)
            {
                this.Popup -= this.m_EvtPopup;
            }
            base.Dispose(disposing);
        }
    #endregion
    }
} 

Mam więc projekt, w którym znajduje się silnik bazujący na toolTipach, ktróre automatycznie przyklejają się do kontrolek jeśli klasa zostanie zastosowana.
Moim zadaniem jest podpięcie tego rozszerzenia pod ten silnik.

Jeżeli więc mamy parametr, który w całej klasie jest wykorzystywany jako ToolTip

 private ToolTip errorTooltip

i zamienie go na:

  private EnhancedToolTip errorTooltip

Podmiana w takiej formie nie pozwala mi korzystać z parametru jak z normalnej funkcjonalności ToolTipa.
Całe rozwiązanie w Visual Studio jest traktowane jako komponent. Gdzie robię błąd? Jak odnieść się do dziedziczonej funkcjonalności?

0

Musisz dokładniej zdefiniować problem bo wątpię, że ktoś Ci pomoże. Mieszasz moim zdaniem trochę słownictwo, co może być mylące. Zatem:

  1. Co chcesz osiągnąć? (kod?)
  2. Jak próbujesz to osiągnąć? (kod?)
  3. Co oznacza "odniesienie się do dziedziczonej funkcjonalności"? Chodzi Ci o wywołanie metody bazowej?
  4. "Podmiana w takiej formie nie pozwala mi korzystać z parametru jak z normalnej funkcjonalności ToolTipa." - z jakiego parametru nie możesz skorzystać?

Zwróć również uwagę, że kontrolka nie ma bezparametrowego konstruktora co z tego co wiem nie zadziała z Designerem Visual Studio.

0

W skrócie chcę wyświetlić notyfikacje z ToolTipa, nad kontrolką która została wyłączona (Disabled). Uznałem, że powyższe rozwiązanie przybliży mnie do celu, ale średnio umiem je zastosować, ergo nie umiem zwerbalizować problemu.

0

Jeżeli dobrze rozumiem Twój cel, to możesz to zrobić tak:

Podpinasz się pod event EnabledChange kontrolki. Kiedy ten event jest odpalany i Enabled jest ustawiane na false to pokazujesz ToolTip. Całość można ładnie zautomatyzować podpinająć do wszystkich kontrolek tę samą delegatę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1