Событие перемещения мыши не работает внутри WindowsFormsHost - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть кнопка внутри 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;
    }
}

1 Ответ

0 голосов
/ 25 апреля 2020

Повторное размещение моего комментария в качестве ответа для кармы:

  • У WinForms и WPF очень разные системы разметки: WinForms наследует концепцию VB6 "все абсолютно позиционировано", используя только X, Y , Width и Height, который очень прост в использовании, но означает, что формы должны иметь фиксированный размер или кодироваться вручную для обработки событий изменения размера, что является реализацией PITA.
    • WinForms добавили свойства Anchor и Dock для очень базовых c макетов.
    • В. NET Framework 2.0, WinForms добавили FlowLayoutPanel и TableLayoutPanel что также помогло.
    • FlowLayoutPanel и TableLayoutPanel обрабатывают абсолютное позиционирование элементов для вас, что означает, что вы не можете напрямую установить координаты элемента управления (или, точнее, установить координаты, просто позиционируя элемент управления относительно его содержимого). панель или ячейка).
  • WPF, однако, использует совершенно другую систему компоновки, которая вообще не использует абсолютное позиционирование (вы можете устанавливать координаты только внутри элемента WPF <Canvas>), вместо этого он имеет хороший ассортимент встроенных элементов управления макетом, таких как StackPanel, DockPanel, WrapPanel и другие, что гораздо более гибко, чем aneami c элементов управления макетом WinForm.
    • WPF и XAML были разработаны для поддержки как пользовательского интерфейса приложения, так и «документов» (помните злополучного конкурента Microsoft в области PDF «XPS»? Это было основано на модели макета XAML), поэтому он гораздо более гибкий, чем WinForms 'model.
    • Однако в WPF есть серьезные проблемы с эргономикой для программистов, например, они позволяют использовать только один дочерний элемент управления для каждой ячейки Panel (идея заключается в том, что вы должны использовать другой <Panel> в качестве дочернего элемента элемента управления макетом, а затем добавьте к нему дочерние элементы - но вначале он очень интуитивно понятен после использования в вездесущем WinForm ControlsCollection).
  • Так что я хочу сказать, что WPF и У WinForms принципиально разные модели макетов, поэтому не используйте методы WPF с WinForms и наоборот - поэтому WinForms FlowLayoutPanel не работает так, как вы думаете - если вы думаете, что он работает как WPF WrapPanel.
  • Поскольку WinForm FlowLayoutPanel «контролирует» положение и размер дочерних элементов управления, это означает, что setti ng 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>
...