2013-09-20 4 views
0

Я пытаюсь изменить свойство BackColor элемента управления пользователя и ForeColor ярлыка внутри него. Следующий мой код:Невозможно изменить BackColor User Control на события Mouse_Enter и Mouse_Leave

private void NRow_MouseLeave(object sender, EventArgs e) 
{ 
    BackColor = Color.White; 
    label1.ForeColor = Color.Black; 
} 

private void NRow_MouseEnter(object sender, EventArgs e) 
{ 
    BackColor = Color.Lime; 
    label1.ForeColor = Color.White; 
} 

Но его не работает. Даже я попытался добавить точку останова на строку изменения BackColor, но контроль там не доходит. Я также проверил привязку события, это нормально. Пользовательский элемент управления добавляется на панель следующим образом:

notContainer.Controls.Add(new NRow()); 

Я не знаю, что происходит. Пожалуйста помоги.

UPDATE:

обработчики событий прикреплены так:

this.MouseEnter += new System.EventHandler(this.NRow_MouseEnter); 
this.MouseLeave += new System.EventHandler(this.NRow_MouseLeave); 
+0

Как вы прикрепляете обработчики событий к вашему UserControl? –

+0

см. Мой обновленный вопрос. –

+5

MouseEnter/Leave очень ненадежны для UserControl. Элементы управления внутри этого UC имеют тенденцию получать событие. Единственным достойным решением является таймер, который проверяет флажок «Cursor.Position». Проверьте [этот ответ] (http://stackoverflow.com/a/12553029/17034) –

ответ

2

Если ваш label1 помещенной внутри пользовательского элемента управления (UC) NRow, вы должны обращаться MouseEnter и MouseEvent из label1 тоже. Потому что ваш label1 внутри вашего UC может обрабатывать ваши события мыши вместо вашего UC, когда мышь перемещается по нему.

this.MouseEnter += new System.EventHandler(this.NRow_MouseEnter); 
this.MouseLeave += new System.EventHandler(this.NRow_MouseLeave);  
label1.MouseEnter += new System.EventHandler(this.NRow_MouseEnter); 
label1.MouseLeave += new System.EventHandler(this.NRow_MouseLeave); 

Примечание: все вышеуказанные строки должны быть размещены внутри вашего UC NRow.

2

Я был в состоянии заставить его работать переопределением UserControl'sOnMouseLeave и OnMouseEnter и используя PointToClient метод, чтобы определить, если координаты мыши все еще в UserControl Прежде чем вернуться, если что-то вроде это работает для вас.

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 
    protected override void OnMouseEnter(EventArgs e) 
    { 
     BackColor = Color.Lime; 
     label1.ForeColor = Color.White; 

     base.OnMouseEnter(e); 
    } 

    protected override void OnMouseLeave(EventArgs e) 
    { 
     if (! Bounds.Contains(PointToClient(MousePosition))) 
     { 
      BackColor = Color.White; 
      label1.ForeColor = Color.Black; 
      base.OnMouseLeave(e); 
     }   
    } 
} 
+0

Простой, и ясно. +1 –

1

Вы можете попробовать этот код, чтобы передавать сообщения от child controls к вашему UserControl, в вашем случае вам нужно передать сообщение WM_MOUSEMOVE плюс некоторый небольшой код, чтобы заставить его работать, как ожидалось:

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent();    
    } 
    Dictionary<Control,NativeControl> controls = new Dictionary<Control,NativeControl>(); 
    protected override void OnLostFocus(EventArgs e) 
    { 
     base.OnLostFocus(e); 
     OnMouseLeave(e); 
    }     
    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     e.Control.HandleCreated += ControlsHandleCreated; 
     base.OnControlAdded(e); 
    } 
    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     e.Control.HandleCreated -= ControlsHandleCreated; 
     base.OnControlRemoved(e); 
    } 
    private void ControlsHandleCreated(object sender, EventArgs e) 
    { 
     Control control = sender as Control; 
     NativeControl nc; 
     if(!controls.TryGetValue(control, out nc)) { 
      nc = new NativeControl(this); 
      controls[control] = nc; 
     } 
     nc.AssignHandle(control.Handle);    
    }   
    public class NativeControl : NativeWindow 
    { 
     public NativeControl(UserControl1 parent) 
     { 
      Parent = parent; 
     } 
     UserControl1 Parent; 
     bool entered; 
     protected override void WndProc(ref Message m) 
     { 
      //WM_MOUSEMOVE = 0x200 
      //WM_LBUTTONDOWN = 0x201 
      //WM_LBUTTONUP = 0x202 
      //WM_NCHITTEST = 0x84 
      if (m.Msg == 0x200 || m.Msg == 0x201 || m.Msg == 0x202 || m.Msg == 0x84){ 
       //Check if Parent is not nul, pass these messages to the parent 
       if (Parent != null){ 
        m.HWnd = Parent.Handle; 
        Parent.WndProc(ref m); 
       } 
       if (m.Msg == 0x200 && !entered){ 
        entered = true; 
        Parent.OnMouseEnter(EventArgs.Empty); 
       } 
       else entered = false; 
      } 
      else if (entered) entered = false; 
      base.WndProc(ref m);     
     } 
    } 
}