单击并拖动图像上的框 - WPF

时间:2014-05-30 18:28:00

标签: c# wpf image xaml

我无法让selectionBox无法居中。在下面的图片中,我尝试通过单击并拖动来围绕单词 Final Bill (重音ms画框)绘制一个框,但生成的selectionBox(虚线为红色)始终输出从中心开始。在mouseUp事件中计算和保存的矩形值都是正确的,这表明可能存在XAML显示问题?

我非常了解WPF / XAML和前端的东西。

编辑:只需将selectionBox放在<Canvas>标签中,我就能让它快完成了。它不再居中,但起点似乎是左侧和顶部边界的两倍,因为点击时鼠标就是这样。

XAML output

XAML

<DockPanel Width="Auto" Margin="225,65,5,5">
    <Border x:Name="img_Border" ClipToBounds="True" Height="Auto" Width="Auto" Margin="0,0,0,0" VerticalAlignment="Top">
        <Grid>
            <ScrollViewer>
                <Image x:Name="img_Box" ClipToBounds="True" MouseMove="img_Box_MouseMove" MouseWheel="img_Box_MouseWheel">
                </Image>
            </ScrollViewer>
            <Rectangle x:Name="selectionBox" Visibility="Collapsed" Stroke="Red" StrokeThickness="3" StrokeDashArray="3,1">
            </Rectangle>
        </Grid>
    </Border>
</DockPanel>

如果我使用selectionBox标记,我可以让<Canvas>正常工作。但这会导致图像不适合<DockPanel>

C#

public MainWindow()
{
    InitializeComponent();

    img_Box.MouseLeftButtonDown += img_Box_MouseLeftButtonDown;
    img_Box.MouseLeftButtonUp += img_Box_MouseLeftButtonUp;
    img_Box.MouseMove += img_Box_MouseMove;

    Point mouseDownPos;
}

private void img_Box_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    img_Box.CaptureMouse();
    var tt = (TranslateTransform)((TransformGroup)img_Box.RenderTransform).Children.First(tr => tr is TranslateTransform);

    double BoxX = (e.GetPosition(img_Box).X / img_Box.ActualWidth) * 1;
    double BoxY = (e.GetPosition(img_Box).Y / img_Box.ActualHeight) * 1;
    double xValue = Math.Round((BoxX * img_Box.Source.Width), 0);
    double yValue = Math.Round((BoxY * img_Box.Source.Height), 0);

    StartDrag = new System.Windows.Point(xValue, yValue);
    mouseDownPos.X = (int)xValue;
    mouseDownPos.Y = (int)yValue;

    Canvas.SetLeft(selectionBox, xValue);
    Canvas.SetTop(selectionBox, yValue);
    selectionBox.Width = 0;
    selectionBox.Height = 0;
    selectionBox.Visibility = Visibility.Visible;
}

private void img_Box_MouseMove(object sender, MouseEventArgs e)
{
    double x = e.GetPosition(img_Box).X;
    double y = e.GetPosition(img_Box).Y;
    double BoxX = (x / img_Box.ActualWidth) * 1;
    double BoxY = (y / img_Box.ActualHeight) * 1;
    double xValue = Math.Round((BoxX * img_Box.Source.Width), 0);
    double yValue = Math.Round((BoxY * img_Box.Source.Height), 0);

    if (mouseDownPos.X < xValue)
    {
        Canvas.SetLeft(selectionBox, mouseDownPos.X);
        selectionBox.Width = xValue - mouseDownPos.X;
    }
    else
    {
        Canvas.SetLeft(selectionBox, xValue);
        selectionBox.Width = mouseDownPos.X - xValue;
    }
    if (mouseDownPos.Y < yValue)
    {
        Canvas.SetTop(selectionBox, mouseDownPos.Y);
        selectionBox.Height = yValue - mouseDownPos.Y;
    }
    else
    {
        Canvas.SetTop(selectionBox, yValue);
        selectionBox.Height = mouseDownPos.Y - yValue;
    }
}

1 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解你在这里想要完成什么,但是如果你只需要在该文本周围使用边框而不允许用户使用鼠标移动它,请将图像设置为网格然后对网格进行分区,使其中一个网格单元格直接位于要放置边框的文本上方。将边框放在该单元格中如果所有的帐单图像大小完全相同并且文本位于完全相同的位置,只要您不允许用户调整图像大小,它就会直接在该文本上... ...如果你想要滚动只需将整个网格放在ScrollViewer控件中。

这样的事情:

  <Grid>  
  <Grid.Background>
    <VisualBrush TileMode="None" >
      <VisualBrush.Visual>
        <Image Source="{Binding ImageSource}"/>
      </VisualBrush.Visual>
    </VisualBrush>
  </Grid.Background>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="80"/> //Distance from the left edge of the image to the right edge of the border around the "Final Bill" text.
    </Grid.ColumnDefinitions>    
    <Grid.RowDefinitions>
      <RowDefinition Height="150"/> //Distance from the top of the image to the top of the desired location of the border around the "Final Bill" text.
      <RowDefinition Height="50"/> //Desired height of the border around the "Final Bill" text.
    </Grid.RowDefinitions>
    <Border Grid.Column="0" Grid.Row="1" BorderThickness="1"/>
  </Grid>