鼠标移动事件在 WindowsFormsHost 中不起作用
Mouse move event is not working inside WindowsFormsHost
我在 WinformHost 中有一个按钮,我想使用鼠标将它移动到 WindowsFormsHost 中的任何位置。我做了如下。但是当鼠标移到按钮上时它会闪烁。请帮忙指正
<Grid x:Name="myGrid" Background="Transparent" Height="400" Width="700">
<WindowsFormsHost Height="200" HorizontalAlignment="Left" Margin="10,108,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="200" Background="PaleVioletRed">
<wf:FlowLayoutPanel Name="FlowPanel" BackColor="Red" Dock="Fill">
<wf:Panel.Controls>
<wf:Button x:Name="Btn1" MouseMove="Btn1_MouseMove" MouseDown="Btn1_MouseDown" Width="120" Height="120" Text="BTN1" BackColor="yellow"></wf:Button>
<wf:Button x:Name="Btn2" Width="120" Height="120" Text="BTN2" BackColor="Red"></wf:Button>
</wf:Panel.Controls>
</wf:FlowLayoutPanel>
</WindowsFormsHost>
</Grid>
private System.Drawing.Point MouseDownLocation;
private void Btn1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
btn1.Left = e.X + btn1.Left - MouseDownLocation.X;
btn1.Top = e.Y + btn1.Top - MouseDownLocation.Y;
}
}
private void Btn1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
重新发布我的评论作为业力的答案:
- WinForms 和 WPF 具有非常不同的布局系统:WinForms 仅使用
X
、Y
、Width
和 Height
继承了 VB6 的 "everything is absolutely positioned" 概念,其中使用起来非常简单,但是意味着表单需要具有固定大小或需要手动编码来处理调整大小事件,这是一个 PITA 来实现。
- WinForms 确实为非常基本的布局添加了
Anchor
和 Dock
属性。
- 在 .NET Framework 2.0 中,WinForms 添加了
FlowLayoutPanel
和 TableLayoutPanel
,这也有帮助。
FlowLayoutPanel
和 TableLayoutPanel
为您处理元素的绝对定位,这意味着您不能直接设置控件的坐标(或者更确切地说,设置坐标只是相对于其包含面板定位控件或细胞)。
- 然而,WPF 使用了一个非常不同的布局系统,它根本不使用绝对定位(您只能在 WPF
<Canvas>
元素内设置坐标),相反它有各种各样的内置StackPanel
、DockPanel
、WrapPanel
等布局控件 - 比 WinForm 的 aneamic 布局控件灵活得多。
- WPF 和 XAML 旨在同时支持应用程序 UI 和 "documents"(还记得微软命运多舛的 PDF 竞争对手 "XPS" 吗?那是基于 XAML 的布局模型)——这就是为什么它比 WinForms 的模型灵活得多。
- 但是,WPF 存在主要的程序员人机工程学问题,例如设计为每个
Panel
单元格仅允许一个子控件(想法是您应该使用另一个 <Panel>
作为子控件布局控件,然后向其添加子项 - 但在习惯了 WinForm 无处不在的 ControlsCollection
). 之后,一开始它非常违反直觉
- 所以我的观点是 WPF 和 WinForms 具有根本不同的布局模型,所以不要将 WPF 技术与 WinForms 一起使用,反之亦然 - 这就是为什么 WinForms 的
FlowLayoutPanel
不起作用的原因你认为它确实如此 - 如果你认为它像 WPF 的 WrapPanel
.
- 因为 WinForm 的
FlowLayoutPanel
"takes control" 超过其子控件的位置和大小,这意味着设置 Left
和 Top
(可能还有 Width
和 Height
取决于 Dock
和 Anchor
设置)在每个子控件上都是徒劳的,因为它们将被 FlowLayoutPanel
. 覆盖
- 所以如果想绝对设置WinForms控件的位置,那么根本不用
FlowLayoutPanel
,直接把控件加到父级的ControlsCollection
上,然后设置坐标和大小即可.
WindowsFormsHost
是一个WPF控件,不是WinForms控件,所以它只能有一个WinForms控件作为它的内容(.Child
属性)。使用 WinForms Panel
控件来创建一个简单的 WinForms 控件集合,这些控件的位置和大小是手动设置的。
像这样:
<Grid
x:Name="myGrid"
Background="Transparent"
Height="400"
Width="700"
>
<WindowsFormsHost
Height="200"
HorizontalAlignment="Left"
Margin="10,108,0,0"
Name="windowsFormsHost1"
VerticalAlignment="Top"
Width="200"
Background="PaleVioletRed"
>
<wf:Panel
Name="FlowPanel"
BackColor="Red"
Dock="Fill"
>
<wf:Panel.Controls>
<wf:Button
x:Name="Btn1"
MouseMove="Btn1_MouseMove"
MouseDown="Btn1_MouseDown"
Width="120"
Height="120"
Text="BTN1"
BackColor="yellow"
/>
<wf:Button
x:Name="Btn2"
Width="120"
Height="120"
Text="BTN2"
BackColor="Red
/>
</wf:Panel.Controls>
</wf:Panel>
</WindowsFormsHost>
</Grid>
我在 WinformHost 中有一个按钮,我想使用鼠标将它移动到 WindowsFormsHost 中的任何位置。我做了如下。但是当鼠标移到按钮上时它会闪烁。请帮忙指正
<Grid x:Name="myGrid" Background="Transparent" Height="400" Width="700">
<WindowsFormsHost Height="200" HorizontalAlignment="Left" Margin="10,108,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="200" Background="PaleVioletRed">
<wf:FlowLayoutPanel Name="FlowPanel" BackColor="Red" Dock="Fill">
<wf:Panel.Controls>
<wf:Button x:Name="Btn1" MouseMove="Btn1_MouseMove" MouseDown="Btn1_MouseDown" Width="120" Height="120" Text="BTN1" BackColor="yellow"></wf:Button>
<wf:Button x:Name="Btn2" Width="120" Height="120" Text="BTN2" BackColor="Red"></wf:Button>
</wf:Panel.Controls>
</wf:FlowLayoutPanel>
</WindowsFormsHost>
</Grid>
private System.Drawing.Point MouseDownLocation;
private void Btn1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
btn1.Left = e.X + btn1.Left - MouseDownLocation.X;
btn1.Top = e.Y + btn1.Top - MouseDownLocation.Y;
}
}
private void Btn1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
重新发布我的评论作为业力的答案:
- WinForms 和 WPF 具有非常不同的布局系统:WinForms 仅使用
X
、Y
、Width
和Height
继承了 VB6 的 "everything is absolutely positioned" 概念,其中使用起来非常简单,但是意味着表单需要具有固定大小或需要手动编码来处理调整大小事件,这是一个 PITA 来实现。- WinForms 确实为非常基本的布局添加了
Anchor
和Dock
属性。 - 在 .NET Framework 2.0 中,WinForms 添加了
FlowLayoutPanel
和TableLayoutPanel
,这也有帮助。 FlowLayoutPanel
和TableLayoutPanel
为您处理元素的绝对定位,这意味着您不能直接设置控件的坐标(或者更确切地说,设置坐标只是相对于其包含面板定位控件或细胞)。
- WinForms 确实为非常基本的布局添加了
- 然而,WPF 使用了一个非常不同的布局系统,它根本不使用绝对定位(您只能在 WPF
<Canvas>
元素内设置坐标),相反它有各种各样的内置StackPanel
、DockPanel
、WrapPanel
等布局控件 - 比 WinForm 的 aneamic 布局控件灵活得多。- WPF 和 XAML 旨在同时支持应用程序 UI 和 "documents"(还记得微软命运多舛的 PDF 竞争对手 "XPS" 吗?那是基于 XAML 的布局模型)——这就是为什么它比 WinForms 的模型灵活得多。
- 但是,WPF 存在主要的程序员人机工程学问题,例如设计为每个
Panel
单元格仅允许一个子控件(想法是您应该使用另一个<Panel>
作为子控件布局控件,然后向其添加子项 - 但在习惯了 WinForm 无处不在的ControlsCollection
). 之后,一开始它非常违反直觉
- 所以我的观点是 WPF 和 WinForms 具有根本不同的布局模型,所以不要将 WPF 技术与 WinForms 一起使用,反之亦然 - 这就是为什么 WinForms 的
FlowLayoutPanel
不起作用的原因你认为它确实如此 - 如果你认为它像 WPF 的WrapPanel
. - 因为 WinForm 的
FlowLayoutPanel
"takes control" 超过其子控件的位置和大小,这意味着设置Left
和Top
(可能还有Width
和Height
取决于Dock
和Anchor
设置)在每个子控件上都是徒劳的,因为它们将被FlowLayoutPanel
. 覆盖
- 所以如果想绝对设置WinForms控件的位置,那么根本不用
FlowLayoutPanel
,直接把控件加到父级的ControlsCollection
上,然后设置坐标和大小即可. WindowsFormsHost
是一个WPF控件,不是WinForms控件,所以它只能有一个WinForms控件作为它的内容(.Child
属性)。使用 WinFormsPanel
控件来创建一个简单的 WinForms 控件集合,这些控件的位置和大小是手动设置的。
像这样:
<Grid
x:Name="myGrid"
Background="Transparent"
Height="400"
Width="700"
>
<WindowsFormsHost
Height="200"
HorizontalAlignment="Left"
Margin="10,108,0,0"
Name="windowsFormsHost1"
VerticalAlignment="Top"
Width="200"
Background="PaleVioletRed"
>
<wf:Panel
Name="FlowPanel"
BackColor="Red"
Dock="Fill"
>
<wf:Panel.Controls>
<wf:Button
x:Name="Btn1"
MouseMove="Btn1_MouseMove"
MouseDown="Btn1_MouseDown"
Width="120"
Height="120"
Text="BTN1"
BackColor="yellow"
/>
<wf:Button
x:Name="Btn2"
Width="120"
Height="120"
Text="BTN2"
BackColor="Red
/>
</wf:Panel.Controls>
</wf:Panel>
</WindowsFormsHost>
</Grid>