WPF之Canvas不能添加ScrollViewer问题的终极解决方案

**前言?*本人是个学习WPF的新手,期间遇到了很多问题,今天在项目上遇到了一个特别麻烦的问题,就是Canvas不能添加滑动条,我原先的想法是用Canvas作为父容器,之所以采用Canvas作为父容器,是因为它可以实现绝对布局,可以方便的通过程序来控制子控件的位置,可以实现动态的往里面添加图片,然后可以加个滚动条实时的浏览传过来的图片,如果跟我有相同想法的朋友可以看一下我在实现这个功能的过程中遇到的种种问题。最后经过一系列的查找资料,不断的调试程序终于解决了。

(1)通过查找资料说可以给Canvas加个StackPanel,于是我尝试了一下,代码布局如下:

 <ScrollViewer Height="845"
                HorizontalScrollBarVisibility="Auto"
                  VerticalScrollBarVisibility="Visible">
        <StackPanel Height="Auto" Width="1395" x:Name="stackPanelFather">
        <Canvas x:Name="father" Width="1395" Height="Auto" SizeChanged="Father_SizeChanged">
        </Canvas>
        </StackPanel>
    </ScrollViewer>

我的想法很简单,将Canvas的Height设置成Auto,这样就可以动态的往里面添加图片了,然后在Canvas外层加了一个StackPanel,也不限定它的高度,这种做法相当于是给StackPanel加了滑动条,它里面只有Canvas这一个子控件,虽然子控件的高度并没有限制,但是你会发现,你主窗体的高度却限制住了它,调式的结果是只能显示主窗体高度的图片数,有点小失望,然后果断的抛弃了这种方法
(2)第二种方法替换Canvas,采用WrapPanel,提前做一个用户控件用来存放图片,然后将该用户控件添加到WrapPanel中。为什么要做一个用户控件来存放图片呢?,因为用户控件格式和布局可以自己设置,而WrapPanel不好设置子控件的位置,所以提前将模板做好,之后直接放入到WrapPanel中就好。代码布局如下:

<ScrollViewer Height="845"
                HorizontalScrollBarVisibility="Auto"
                  VerticalScrollBarVisibility="Visible">
        <WrapPanel Orientation="Horizontal" x:Name="stackPanelFather" Width="1395" Height="Auto" SizeChanged="Father_SizeChanged">

        </WrapPanel>
    </ScrollViewer>

当然了动态的添加图片和刷新图片的过程需要用到委托机制,但是不管怎样最后还是顺利的解决了这个问题。
(3)最后贴一个实现的效果图:在这里插入代码片在这里插入图片描述
欢迎评论和留言,具体的代码实现逻辑这里就不做详细介绍了,有想知道怎么实现的可以给我留言,我一般都会回复的~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF 中,可以使用 `Canvas` 控件的 `MouseMove` 事件和 `MouseLeftButtonDown`、`MouseLeftButtonUp` 事件结合起来实现鼠标在 `Canvas` 控件中按住移动时不能超过 `Canvas` 边界的效果。 具体实现可以参考以下代码: ```xaml <Canvas x:Name="canvas" Width="300" Height="200" Background="White" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseMove="Canvas_MouseMove" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" /> ``` ```csharp private bool isDrawing = false; private Point startPoint; private Point endPoint; private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { isDrawing = true; startPoint = e.GetPosition(canvas); } private void Canvas_MouseMove(object sender, MouseEventArgs e) { if (isDrawing) { endPoint = e.GetPosition(canvas); // 计算鼠标在 Canvas 中的坐标,并限制移动范围 double x = Math.Min(Math.Max(endPoint.X, 0), canvas.ActualWidth); double y = Math.Min(Math.Max(endPoint.Y, 0), canvas.ActualHeight); // 绘制路径 Line line = new Line { Stroke = Brushes.Black, X1 = startPoint.X, Y1 = startPoint.Y, X2 = x, Y2 = y }; canvas.Children.Add(line); // 更新起点坐标 startPoint = new Point(x, y); } } private void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { isDrawing = false; } ``` 在上述代码中,我们在 XAML 中定义了一个 `Canvas` 控件,并添加了 `MouseLeftButtonDown`、`MouseMove`、`MouseLeftButtonUp` 事件的处理函数。当鼠标左键按下时,设置 `isDrawing` 为 `true`,并记录下起点坐标。当鼠标移动时,如果 `isDrawing` 为 `true`,则计算出鼠标在 `Canvas` 中的坐标,并限制移动范围。然后绘制路径,并更新起点坐标。当鼠标左键抬起时,设置 `isDrawing` 为 `false`,结束绘制。 注意,WPF 中的 `Canvas` 控件大小可以通过 `Width` 和 `Height` 属性来设置,但实际大小可能会受到父控件的布局影响。因此,在计算鼠标在 `Canvas` 中的坐标时,需要使用 `ActualWidth` 和 `ActualHeight` 属性来获取 `Canvas` 控件的实际大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值