UserControl 的子项在移动后消失
Children of a UserControl disappear after moving
我遇到了一个很严重的问题。
我通过使用 MouseDown, MouseMove,MouseUp
事件在其父项中创建了一个可移动的 UserControl(如 window)。
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
属性用于我可以在 VS 的设计器中向此 UserControl 添加控件。
州:
- 移动这些 UserControl 效果很好(Usercontrol 按预期移动...)
- 可以在 VS 的设计器中添加控件,并在运行时按设计显示[可见,应该如此]
- 通过移动 UserControl,子项变得不可见,但
.Visible=true
没有改变
.BringToFront();
没有影响(我以为他们可能在容器后面)
这是用户控件 class:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class MovableContainer : UserControl
{
bool mdown = false;
Point mpos;
[EditorBrowsable(EditorBrowsableState.Always)]
[SettingsBindable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Axis Rasta { get; set; }
public static int DefautlRasta = 10;
public MovableContainer()
{
rasta = DefautlRasta;
InitializeComponent();
this.MouseDown += ((object o, MouseEventArgs e) =>
{
mdown = true;
mpos = this.PointToClient(MousePosition);
});
this.MouseUp += ((object o, MouseEventArgs e) => mdown = false);
this.MouseMove += MovableContainer_MouseMove;
this.Paint += (object o, PaintEventArgs e) =>
{
Console.WriteLine("BTF");
this.Parent.Controls.OfType<Control>().ToList().ForEach(x => x.BringToFront());
this.Controls.OfType<Control>().ToList().ForEach(x => x.BringToFront());
this.Controls.OfType<Control>().ToList().ForEach(x => x.Show());
};
this.ParentChanged += ((object o, EventArgs e) =>
{
if (this.Parent == null)
{
try { this.Parent.SizeChanged -= Parent_SizeChanged; }
catch { }
}
else
{
try { this.Parent.SizeChanged += Parent_SizeChanged; }
catch { }
}
}
);
// this.KeyDown += ((object o, KeyEventArgs e) => {
///kdown = (RastaKey == e.KeyCode); Console.WriteLine("K:"+kdown);
//});
//this.KeyUp += ((object o, KeyEventArgs e) => kdown = false);
}
void Parent_SizeChanged(object sender, EventArgs e)
{
this.Boundis = new Rectangle(Parent.Padding.Left, Parent.Padding.Top, Parent.Size.Width - Parent.Padding.Horizontal, Parent.Size.Height - Parent.Padding.Vertical);
{
this.Location = this.Location.Add(this.PointToClient(MousePosition).Sub(mpos)).Rasta(Rasta, rasta);
Rectangle rct = new Rectangle(this.Location, this.Size);
if (this.Boundis.X > rct.X)
{
this.Location = new Point(this.Boundis.X, this.Location.Y);
Console.Write("R");
}
//left
if (this.Boundis.Right < rct.Right)
{
this.Location = new Point(this.Boundis.Right - rct.Width, rct.Y);
Console.Write("L");
}
//top
if (this.Boundis.Y > rct.Y)
{
this.Location = new Point(rct.X, this.Boundis.Y);
Console.Write("T");
}
//bottom
if (this.Boundis.Bottom < rct.Bottom)
{
this.Location = new Point(rct.X, this.Boundis.Bottom - rct.Height);
Console.Write("B");
}
Console.WriteLine();
}
}
void MovableContainer_MouseMove(object sender, MouseEventArgs e)
{
if (mdown)
{
this.Location = this.Location.Add(this.PointToClient(MousePosition).Sub(mpos)).Rasta(Rasta, rasta);
Rectangle rct = new Rectangle(this.Location, this.Size);
if (this.Boundis.X > rct.X)
{
this.Location = new Point(this.Boundis.X, this.Location.Y);
Console.Write("R");
}
//left
if (this.Boundis.Right < rct.Right)
{
this.Location = new Point(this.Boundis.Right - rct.Width, rct.Y);
Console.Write("L");
}
//top
if (this.Boundis.Y > rct.Y)
{
this.Location = new Point(rct.X, this.Boundis.Y);
Console.Write("T");
}
//bottom
if (this.Boundis.Bottom < rct.Bottom)
{
this.Location = new Point(rct.X, this.Boundis.Bottom - rct.Height);
Console.Write("B");
}
Console.WriteLine();
}
}
public Rectangle Boundis { get; set; }
}
public enum Axis { X, Y, None }
那么,我该如何解决这个问题?
坦率地说,您发布的代码一团糟 - 您放在那里的大部分内容都没有意义。据我所知,您正在尝试实现 运行 时间可移动容器并进行剪裁。一个简单的继承 Panel
会做同样的事情 w/o 那些设计器属性等的需要。无论如何,你描述的问题是由你的 Parent_SizeChanged
处理程序中的错误计算引起的。这是一段经过部分清理的代码,它可以执行我认为您正在尝试执行的操作 w/o 遇到任何问题:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class MovableContainer : UserControl
{
bool mdown = false;
Point mpos;
int rasta;
Control parent;
[EditorBrowsable(EditorBrowsableState.Always)]
[SettingsBindable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Axis Rasta { get; set; }
public static int DefautlRasta = 10;
public MovableContainer()
{
rasta = DefautlRasta;
InitializeComponent();
this.MouseDown += (sender, e) =>
{
mdown = true;
mpos = e.Location;
};
this.MouseUp += (sender, e) =>
{
mdown = false;
};
this.MouseMove += (sender, e) =>
{
if (mdown)
SetLocation(this.Location.Add(e.Location.Sub(mpos)).Rasta(Rasta, rasta));
};
EventHandler onParentSizeChanged = (sender, e) =>
{
SetLocation(this.Location);
};
this.ParentChanged += (sender, e) =>
{
if (parent != null) parent.SizeChanged -= onParentSizeChanged;
parent = Parent;
if (parent != null) parent.SizeChanged += onParentSizeChanged;
};
}
private void SetLocation(Point location)
{
var rect = new Rectangle(location, Size);
var clipRect = Parent.DisplayRectangle;
if (rect.Right > clipRect.Right) rect.X -= (rect.Right - clipRect.Right);
if (rect.X < clipRect.X) rect.X = clipRect.X;
if (rect.Bottom > clipRect.Bottom) rect.Y -= (rect.Bottom - clipRect.Bottom);
if (rect.Y < clipRect.Y) rect.Y = clipRect.Y;
location = rect.Location;
if (this.Location == location) return;
this.Location = location;
}
}
public enum Axis { X, Y, None }
// You haven't provided these, so I'm guessing by the usage
static class Utils
{
public static Point Add(this Point left, Point right)
{
return new Point(left.X + right.X, left.Y + right.Y);
}
public static Point Sub(this Point left, Point right)
{
return new Point(left.X - right.X, left.Y - right.Y);
}
public static Point Rasta(this Point pt, Axis axis, int value)
{
// Have absolutely no idea what is this about
return pt;
}
}
我遇到了一个很严重的问题。
我通过使用 MouseDown, MouseMove,MouseUp
事件在其父项中创建了一个可移动的 UserControl(如 window)。
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
属性用于我可以在 VS 的设计器中向此 UserControl 添加控件。
州:
- 移动这些 UserControl 效果很好(Usercontrol 按预期移动...)
- 可以在 VS 的设计器中添加控件,并在运行时按设计显示[可见,应该如此]
- 通过移动 UserControl,子项变得不可见,但
.Visible=true
没有改变 .BringToFront();
没有影响(我以为他们可能在容器后面)
这是用户控件 class:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class MovableContainer : UserControl
{
bool mdown = false;
Point mpos;
[EditorBrowsable(EditorBrowsableState.Always)]
[SettingsBindable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Axis Rasta { get; set; }
public static int DefautlRasta = 10;
public MovableContainer()
{
rasta = DefautlRasta;
InitializeComponent();
this.MouseDown += ((object o, MouseEventArgs e) =>
{
mdown = true;
mpos = this.PointToClient(MousePosition);
});
this.MouseUp += ((object o, MouseEventArgs e) => mdown = false);
this.MouseMove += MovableContainer_MouseMove;
this.Paint += (object o, PaintEventArgs e) =>
{
Console.WriteLine("BTF");
this.Parent.Controls.OfType<Control>().ToList().ForEach(x => x.BringToFront());
this.Controls.OfType<Control>().ToList().ForEach(x => x.BringToFront());
this.Controls.OfType<Control>().ToList().ForEach(x => x.Show());
};
this.ParentChanged += ((object o, EventArgs e) =>
{
if (this.Parent == null)
{
try { this.Parent.SizeChanged -= Parent_SizeChanged; }
catch { }
}
else
{
try { this.Parent.SizeChanged += Parent_SizeChanged; }
catch { }
}
}
);
// this.KeyDown += ((object o, KeyEventArgs e) => {
///kdown = (RastaKey == e.KeyCode); Console.WriteLine("K:"+kdown);
//});
//this.KeyUp += ((object o, KeyEventArgs e) => kdown = false);
}
void Parent_SizeChanged(object sender, EventArgs e)
{
this.Boundis = new Rectangle(Parent.Padding.Left, Parent.Padding.Top, Parent.Size.Width - Parent.Padding.Horizontal, Parent.Size.Height - Parent.Padding.Vertical);
{
this.Location = this.Location.Add(this.PointToClient(MousePosition).Sub(mpos)).Rasta(Rasta, rasta);
Rectangle rct = new Rectangle(this.Location, this.Size);
if (this.Boundis.X > rct.X)
{
this.Location = new Point(this.Boundis.X, this.Location.Y);
Console.Write("R");
}
//left
if (this.Boundis.Right < rct.Right)
{
this.Location = new Point(this.Boundis.Right - rct.Width, rct.Y);
Console.Write("L");
}
//top
if (this.Boundis.Y > rct.Y)
{
this.Location = new Point(rct.X, this.Boundis.Y);
Console.Write("T");
}
//bottom
if (this.Boundis.Bottom < rct.Bottom)
{
this.Location = new Point(rct.X, this.Boundis.Bottom - rct.Height);
Console.Write("B");
}
Console.WriteLine();
}
}
void MovableContainer_MouseMove(object sender, MouseEventArgs e)
{
if (mdown)
{
this.Location = this.Location.Add(this.PointToClient(MousePosition).Sub(mpos)).Rasta(Rasta, rasta);
Rectangle rct = new Rectangle(this.Location, this.Size);
if (this.Boundis.X > rct.X)
{
this.Location = new Point(this.Boundis.X, this.Location.Y);
Console.Write("R");
}
//left
if (this.Boundis.Right < rct.Right)
{
this.Location = new Point(this.Boundis.Right - rct.Width, rct.Y);
Console.Write("L");
}
//top
if (this.Boundis.Y > rct.Y)
{
this.Location = new Point(rct.X, this.Boundis.Y);
Console.Write("T");
}
//bottom
if (this.Boundis.Bottom < rct.Bottom)
{
this.Location = new Point(rct.X, this.Boundis.Bottom - rct.Height);
Console.Write("B");
}
Console.WriteLine();
}
}
public Rectangle Boundis { get; set; }
}
public enum Axis { X, Y, None }
那么,我该如何解决这个问题?
坦率地说,您发布的代码一团糟 - 您放在那里的大部分内容都没有意义。据我所知,您正在尝试实现 运行 时间可移动容器并进行剪裁。一个简单的继承 Panel
会做同样的事情 w/o 那些设计器属性等的需要。无论如何,你描述的问题是由你的 Parent_SizeChanged
处理程序中的错误计算引起的。这是一段经过部分清理的代码,它可以执行我认为您正在尝试执行的操作 w/o 遇到任何问题:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class MovableContainer : UserControl
{
bool mdown = false;
Point mpos;
int rasta;
Control parent;
[EditorBrowsable(EditorBrowsableState.Always)]
[SettingsBindable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Axis Rasta { get; set; }
public static int DefautlRasta = 10;
public MovableContainer()
{
rasta = DefautlRasta;
InitializeComponent();
this.MouseDown += (sender, e) =>
{
mdown = true;
mpos = e.Location;
};
this.MouseUp += (sender, e) =>
{
mdown = false;
};
this.MouseMove += (sender, e) =>
{
if (mdown)
SetLocation(this.Location.Add(e.Location.Sub(mpos)).Rasta(Rasta, rasta));
};
EventHandler onParentSizeChanged = (sender, e) =>
{
SetLocation(this.Location);
};
this.ParentChanged += (sender, e) =>
{
if (parent != null) parent.SizeChanged -= onParentSizeChanged;
parent = Parent;
if (parent != null) parent.SizeChanged += onParentSizeChanged;
};
}
private void SetLocation(Point location)
{
var rect = new Rectangle(location, Size);
var clipRect = Parent.DisplayRectangle;
if (rect.Right > clipRect.Right) rect.X -= (rect.Right - clipRect.Right);
if (rect.X < clipRect.X) rect.X = clipRect.X;
if (rect.Bottom > clipRect.Bottom) rect.Y -= (rect.Bottom - clipRect.Bottom);
if (rect.Y < clipRect.Y) rect.Y = clipRect.Y;
location = rect.Location;
if (this.Location == location) return;
this.Location = location;
}
}
public enum Axis { X, Y, None }
// You haven't provided these, so I'm guessing by the usage
static class Utils
{
public static Point Add(this Point left, Point right)
{
return new Point(left.X + right.X, left.Y + right.Y);
}
public static Point Sub(this Point left, Point right)
{
return new Point(left.X - right.X, left.Y - right.Y);
}
public static Point Rasta(this Point pt, Axis axis, int value)
{
// Have absolutely no idea what is this about
return pt;
}
}