2010-01-07 5 views
3

Это вопрос Windows Forms/.Net C#.Как передать сообщения от дочернего пользовательского элемента управления родительскому

У меня есть окна без полей, прозрачность которых и цвет фона делают его полностью прозрачным. Внутри окна находятся несколько пользовательских элементов управления.

Я хочу иметь возможность перемещать окно. Я знаю, как это сделать в родительском окне, но моя проблема в том, что дочерние элементы управления - единственное, что видимо и, следовательно, единственное, что можно щелкнуть.

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

Или, может быть, вы можете предложить другой способ?

Спасибо за помощь.

Марк

+1

Добавить что-то в окно, что делает его очевидным для пользователя, что она может щелкнуть его и переместить окно. Помимо «бычьего глаза» с надписью «нажмите здесь, чтобы переместить», панель заголовков делает очевидный гаджет пользовательского интерфейса. –

ответ

7

Вы можете достичь своей цели даже без SendMessage, используя класс System.Windows.Forms.Message. Если вы сделали перетаскивание, я думаю, вы знакомы с сообщением WM_NCLBUTTONDOWN. Отправьте его родителям из события MouseDown вашего контроля.

Ниже приведен пример перемещения формы, щелкнув на контрольной этикетке1. Обратите внимание на первую строку, в которой отправитель используется для освобождения захваченного элемента управления. Таким образом вы можете установить этот обработчик для всех элементов управления, предназначенных для перемещения вашей формы.

Это полный код для перемещения формы. Больше ничего не нужно.

 

public const int WM_NCLBUTTONDOWN = 0xA1; 
public const int HT_CAPTION = 0x2; 

private void label1_MouseDown(object sender, MouseEventArgs e) 
{ 
     (sender as Control).Capture = false; 
     Message msg = Message.Create(Handle, WM_NCLBUTTONDOWN, (IntPtr)HT_CAPTION, IntPtr.Zero); 
     base.WndProc(ref msg); 
} 
 

Надеюсь, это поможет.

+0

Спасибо за предложение. Несчастливо, код, который вы предоставили, приводит к перемещению UserControl с границами родительской формы. Вид аккуратного эффекта, но, к сожалению, не то, что мне нужно. –

+0

Просто обнаружил, что, изменив Handle в вашем коде родительскому. Handle ... он отлично работает. Большое спасибо за помощь. Теперь мне просто нужно выяснить, как разрешить UserControl обрабатывать некоторые из своих событий мыши и передавать только событие перетаскивания в родительский. Но я чувствую, что я довольно близко. Еще раз спасибо. –

+0

Привет, Марк, пожалуйста. Если вы найдете мой ответ полезным, пожалуйста, отметьте его как полезный или принятый ответ, спасибо. Какие события вы хотите обрабатывать с помощью UserControl? –

0

Вам нужно вызвать функцию SendMessage API для отправки mouse messages на свой родительский контроль.

Возможно, было бы проще всего сделать это, переопределив способ управления вашим WndProc.

+0

Какие сообщения следует записывать в моем WndProc? И я бы просто передал их, как есть (тот же wParam & lParam) родительскому. Хандл? –

+0

Вы должны захватить все сообщения мыши в ссылке. Вам нужно будет скорректировать координаты относительно родительского элемента управления. (Вызов 'PointToScreen', затем' PointToScreen') – SLaks

+1

Спасибо. Кажется, я понял. Но вы говорите, что PointToScreen тогда PointToScreen? Вы имеете в виду PointToScreen, чтобы получить координаты экрана, а затем PointToClient, чтобы передать их клиенту родительского окна? –

7

Я думаю, что самый простой способ, чтобы добавить событие в дочерних элементов управления:

/// <summary> 
/// The event that you will throw when the mouse hover the control while being clicked 
/// </summary> 
public event EventHandler MouseRightClickedAndHoverChildControl; 

После, все родитель должен сделать, это подписаться на эти события и сделать операции перемещения Родитель:

ChildControl.MouseRightClickedAndHoverChildControl += OnMouseHoverChildControl; 

private void OnMouseHoverChildControl(object sender, EventArgs e) 
{ 
    //do foo... 
} 
0

У меня был именно этот вопрос ... но придумал другой ответ. Если у вас есть сообщение в вашем WndProc, вы можете просто сменить дескриптор на свой родительский дескриптор, а затем передать его.

Мне нужно было сделать это в нашем производном текстовом поле ... TextBox ест события прокрутки, даже когда его ScrollBars установлен в None. Я хотел, чтобы они распространялись по Форме. Таким образом, я просто поместить это внутри WndProc для моего производного TextBox:

  case 0x020A: // WM_MOUSEWHEEL 
      case 0x020E: // WM_MOUSEHWHEEL 
       if (this.ScrollBars == ScrollBars.None && this.Parent != null) 
        m.HWnd = this.Parent.Handle; // forward this to your parent 
       base.WndProc(ref m); 
       break; 

      default: 
       base.WndProc(ref m); 
       break; 
Смежные вопросы