【问题标题】:is it possible to move a composite control by clicking on one of its daughter controls?是否可以通过单击其子控件之一来移动复合控件?
【发布时间】:2015-11-04 04:22:21
【问题描述】:

我试图完成的是通过拖放方法移动一堆复合控件,如下图所示:

目前我只能通过复合控件的边缘来做到这一点。是否甚至可以通过单击复合控件中的子/子控件来移动整个复合控件?

这是我将控件添加到主窗体的panel3 的代码:

private void newPictureBox_Click(object sender, EventArgs e)
{
    UserControl1 _UserControl = new UserControl1();
    PictureBox _PictureBox = (PictureBox)sender;
    string _NewControlClusterName = "_New" + _PictureBox.Name;

    _UserControl.Name = _NewControlClusterName;
    _UserControl.ThreadCount = 16;
    _UserControl.ImageBackground = _PictureBox.BackColor;
    _UserControl.Dock = DockStyle.Top;
    _UserControl.AllowDrop = true;
    _UserControl.Cursor = Cursors.SizeAll;

    _UserControl.MouseMove += _UserControl_MouseMove;
    _UserControl.DragDrop += _UserControl_DragDrop;
    _UserControl.DragEnter += _UserControl_DragEnter;

    string ColorName = toolTip1.GetToolTip(_PictureBox);
    string ColorCode = toolTip2.GetToolTip(_PictureBox);
    toolTip1.SetToolTip(_UserControl.pictureBox1, ColorName);
    toolTip2.SetToolTip(_UserControl.pictureBox1, ColorCode);
    toolTip2.Active = false;

    _UserControl.PictureClick += new EventHandler(ClusterControl_Click);
    _UserControl.TrackBarScroll += new EventHandler(GetTartanCode);

    panel3.Controls.Add(_UserControl);
    panel3.Controls.SetChildIndex(_UserControl, 0);
}

private void _UserControl_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;
}

private void _UserControl_DragDrop(object sender, DragEventArgs e)
{
    UserControl1 target = sender as UserControl1;
    if (target != null)
    {
        int targetIndex = FindUserControlIndex(target);
        if (targetIndex != -1)
        {
            string _UserControlFormat = typeof(UserControl1).FullName;
            if (e.Data.GetDataPresent(_UserControlFormat))
            {
                UserControl1 source = e.Data.GetData(_UserControlFormat) as UserControl1;
                int sourceIndex = this.FindUserControlIndex(source);
                if (targetIndex != -1)
                    this.panel3.Controls.SetChildIndex(source, targetIndex);
            }
        }
    }
}

private int FindUserControlIndex(UserControl1 _UserControl)
{
    for (int i = 0; i < this.panel3.Controls.Count; i++)
    {
        UserControl1 target = this.panel3.Controls[i] as UserControl1;
        if (_UserControl == target)
            return i;
    }
    return -1;
}

private void _UserControl_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        UserControl1 _UserControl1 = sender as UserControl1;
        _UserControl1.BorderStyle = BorderStyle.Fixed3D;
        _UserControl1.DoDragDrop(_UserControl1, DragDropEffects.All);
    }
}

private void ClusterControl_Click(object sender, EventArgs e)
{
    PictureBox _PictureBox = (PictureBox)sender;
    GroupBox _GroupBox = (GroupBox)_PictureBox.Parent;
    UserControl1 _UserControl1 = (UserControl1)_GroupBox.Parent;
    panel3.Controls.Remove(_UserControl1);
}

【问题讨论】:

  • 你的意思是在设计时,还是在运行时?

标签: c# winforms drag-and-drop


【解决方案1】:

没有简单的方法可以做到这一点。

您可以尝试将事件处理程序以递归方式附加到每个子控件。
像这样的:

public class UserControl1 : Control
{
    public UserControl1()
    {
        // ...
        ApplyChildEvents(this);
    }

    private void ApplyChildEvents(Control control)
    {
        foreach (Control subcontrol in control.Controls)
        {
            subcontrol.MouseMove += _UserControl_MouseMove;
            subcontrol.DragDrop += _UserControl_DragDrop;
            subcontrol.DragEnter += _UserControl_DragEnter;

            ApplyChildEvents(subcontrol);
        }
    }
}

所以,UserControl1 上的所有控件都会调用此方法。

【讨论】:

  • 这部分我明白,我不明白的是,是否可以通过拖动它的子控件来拖动整个控件。例如,分组框。
  • 好的,通过仅设置组框的属性来更改代码以反映 _USerControl 的动态添加。试图通过组框移动其中一个复合控件,我在 _UserControl_MouseMove 事件处理程序中的 _UserControl1.BorderStyle.Fixed3D; 上得到 NullReferenceException(对象引用未设置为对象的实例)。
  • @JohnSchultz 删除 sender 用法。 Sender 是另一种类型。使用当前对象的属性。
  • 我对该事件处理程序中的代码进行了添加,并将其作为附加答案发布给您。需要这两个答案才能使其正常工作。
  • 后续问题 - 任何有可能为移动设置动画的方法。 IE。当我抓取一个控件时,UI 会将该控件显示为正在移动,而不是鼠标指针和它下方的一个小框?
【解决方案2】:

使用上面的答案以及对 _UserControl_MouseMove 事件处理程序的以下代码调整,它现在可以完美运行。

private void _UserControl_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        if (sender.GetType() == typeof(GroupBox))
        {
            GroupBox _GroupBox = sender as GroupBox;
            UserControl1 _UserControl1 = _GroupBox.Parent as UserControl1;
            _UserControl1.BorderStyle = BorderStyle.Fixed3D;
            _UserControl1.DoDragDrop(_UserControl1, DragDropEffects.All);
        }
        else
        {
            UserControl1 _UserControl1 = sender as UserControl1;
            _UserControl1.BorderStyle = BorderStyle.Fixed3D;
            _UserControl1.DoDragDrop(_UserControl1, DragDropEffects.All);
        }
    }
}

并且还必须将上面的代码更改为以下代码(因为后面提到的区域是动态生成的):

newPictureBox_Click

foreach (Control subcontrol in _UserControl.Controls)
{
    if (subcontrol.GetType() == typeof(GroupBox)){
        subcontrol.MouseMove += _UserControl_MouseMove;
        subcontrol.DragDrop += _UserControl_DragDrop;
        subcontrol.DragEnter += _UserControl_DragEnter;
    }
}

完整代码如下:

private void newPictureBox_Click(object sender, EventArgs e)
{
    UserControl1 _UserControl = new UserControl1();
    PictureBox _PictureBox = (PictureBox)sender;
    string _NewControlClusterName = "_New" + _PictureBox.Name;

    _UserControl.Name = _NewControlClusterName;
    _UserControl.ThreadCount = 16;
    _UserControl.ImageBackground = _PictureBox.BackColor;
    _UserControl.Dock = DockStyle.Top;
    _UserControl.AllowDrop = true;
    _UserControl.Cursor = Cursors.SizeAll;

    _UserControl.MouseMove += _UserControl_MouseMove;
    _UserControl.DragDrop += _UserControl_DragDrop;
    _UserControl.DragEnter += _UserControl_DragEnter;

    string ColorName = toolTip1.GetToolTip(_PictureBox);
    string ColorCode = toolTip2.GetToolTip(_PictureBox);
    toolTip1.SetToolTip(_UserControl.pictureBox1, ColorName);
    toolTip2.SetToolTip(_UserControl.pictureBox1, ColorCode);
    toolTip2.Active = false;

    _UserControl.PictureClick += new EventHandler(ClusterControl_Click);
    _UserControl.TrackBarScroll += new EventHandler(GetTartanCode);

    foreach (Control subcontrol in _UserControl.Controls)
    {
        if (subcontrol.GetType() == typeof(GroupBox)){
            subcontrol.MouseMove += _UserControl_MouseMove;
            subcontrol.DragDrop += _UserControl_DragDrop;
            subcontrol.DragEnter += _UserControl_DragEnter;
        }
    }

    panel3.Controls.Add(_UserControl);
    panel3.Controls.SetChildIndex(_UserControl, 0);
}

private void _UserControl_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.All;
}

private void _UserControl_DragDrop(object sender, DragEventArgs e)
{
    UserControl1 target = sender as UserControl1;
    if (target != null)
    {
        int targetIndex = FindUserControlIndex(target);
        if (targetIndex != -1)
        {
            string _UserControlFormat = typeof(UserControl1).FullName;
            if (e.Data.GetDataPresent(_UserControlFormat))
            {
                UserControl1 source = e.Data.GetData(_UserControlFormat) as UserControl1;

                int sourceIndex = this.FindUserControlIndex(source);

                if (targetIndex != -1)
                    this.panel3.Controls.SetChildIndex(source, targetIndex);
            }
        }
    }
}

private int FindUserControlIndex(UserControl1 _UserControl)
{
    for (int i = 0; i < this.panel3.Controls.Count; i++)
    {
        UserControl1 target = this.panel3.Controls[i] as UserControl1;

        if (_UserControl == target)
            return i;
    }
    return -1;
}

private void _UserControl_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        if (sender.GetType() == typeof(GroupBox))
        {
            GroupBox _GroupBox = sender as GroupBox;
            UserControl1 _UserControl1 = _GroupBox.Parent as UserControl1;
            _UserControl1.BorderStyle = BorderStyle.Fixed3D;
            _UserControl1.DoDragDrop(_UserControl1, DragDropEffects.All);
        }
        else
        {
            UserControl1 _UserControl1 = sender as UserControl1;
            _UserControl1.BorderStyle = BorderStyle.Fixed3D;
            _UserControl1.DoDragDrop(_UserControl1, DragDropEffects.All);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 2015-05-23
    • 2014-12-20
    • 2011-08-24
    • 2011-02-01
    • 1970-01-01
    相关资源
    最近更新 更多