I have a button inside WinformHost and I want to move it to any position inside WindowsFormsHost using mouse. I have done like below. But it is flickering when move the mouse over the button. Please help to correct.
<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;
}
}
Reposting my comment as an answer for the karma:
X
, Y
, Width
and Height
, which is very simple to use, but means that forms need to have a fixed-size or need to be hand-coded to handle resizing events, which is a PITA to implement.
Anchor
and Dock
properties for very basic layouts.FlowLayoutPanel
and TableLayoutPanel
which helped as well.FlowLayoutPanel
and TableLayoutPanel
handle the absolute positioning of elements for you, which means you cannot directly set a control's coordinates (or rather, setting coordinates just positions the control relative to its containing panel or cell).<Canvas>
element), instead it has a good assortment of built-in layout-controls such as StackPanel
, DockPanel
, WrapPanel
, and more - which is far more flexible than WinForm's aneamic layout controls.
Panel
cell (the idea being that you should use another <Panel>
as the child of the layout-control and then add children to that - but it's very counter-intuitive at first after being used to WinForm's ubiquitous ControlsCollection
).FlowLayoutPanel
doesn't work the way you think it does - if you think it works anything like WPF's WrapPanel
.FlowLayoutPanel
"takes control" over the position and size of its child controls, it means that setting Left
and Top
(and possibly Width
and Height
depending on the Dock
and Anchor
settings) on each child control is futile because they'll be overridden by the FlowLayoutPanel
.FlowLayoutPanel
at all, just add the Controls directly to the parent's ControlsCollection
and then set coordinates and size.WindowsFormsHost
is a WPF control, not a WinForms control, so it can only have a single WinForms control as its content (the .Child
property). Use a WinForms Panel
control to have a simple collection of WinForms controls that have their position and size set manually.Like so:
<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>