4

我有一个Grid代表一些数据的,我需要一个Canvas覆盖在它上面来布局一些行。Canvas里面是它自己的UserControl

问题是当调整宽度和高度Canvas时,其及其内容应该自动调整大小。Grid

我添加了Canvas内部 a ViewBox,但它没有成功。当Grid调整大小时,Canvas不会。的目的Canvas是在网格顶部覆盖类似标尺的功能。

期待您的解决方案。

编辑

我不能使用网格上的样式来替换画布,因为网格显示的信息与画布不同。将其视为图表,其中有不同大小的条形列(在我的情况下为网格),而日期是叠加层中的线(就像甘特图一样)

我的代码:

    taxCanvas = new TimeAxis();
    Grid.SetRowSpan(taxCanvas, GRightMain.RowDefinitions.Count);
    Grid.SetColumnSpan(taxCanvas, GRightMain.ColumnDefinitions.Count);

    Grid.SetColumn(taxCanvas, 0);
    Grid.SetRow(taxCanvas, 0);


    Grid.SetZIndex(taxCanvas, -1);

    taxCanvas.Height = GRight.ActualHeight;
    taxCanvas.Width = GRight.ActualWidth;

    GRightMain.Children.Add(taxCanvas);

TimeAxis 是我的画布用户控件,GRightMain 是一个网格,其中包含我的画布和网格,内容(Gright)在同一行和列中。

希望这可以帮助

4

3 回答 3

4

在我看来,画布绝对是错误的方法。

我强烈建议查找 Adorners。您可以创建一个自定义装饰器来执行此操作。

Adorner 基本上是位于所有 UIElement 之上的“非交互式窗口”。它允许你做任何你想做的事情(创建控件,绘制东西,等等),它们会出现在控件本身的顶部。

想象一张木制咖啡桌,上面放着一块透明玻璃。如果你在透明玻璃上画画,你仍然可以看到咖啡桌。唯一的区别是您实际上可以直接穿过咖啡桌上的透明玻璃并触摸木头本身。

我讨厌发布 MSDN 链接……但是……嗯。在这种情况下,这将是一个好的开始:

http://msdn.microsoft.com/en-us/library/ms743737.aspx

编辑:

我迅速把东西扔到一起。希望这有帮助吗?

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:loc="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
  <Grid>
     <loc:GridWithRulerxaml></loc:GridWithRulerxaml>
     <Button Height="20" Width="50" >Click me</Button>
     <TextBox Width="150" Height="25" HorizontalAlignment="Left">This is a text box</TextBox>
  </Grid>
</Window>

用户控制:

<UserControl x:Class="WpfApplication1.GridWithRulerxaml"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
  <Grid>

  </Grid>
</UserControl>

用户控制代码隐藏:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace WpfApplication1
{
  /// <summary>
  /// Interaction logic for GridWithRulerxaml.xaml
  /// </summary>
  public partial class GridWithRulerxaml : UserControl
  {
    public GridWithRulerxaml()
    {
      InitializeComponent();

      //Loaded event is necessary as Adorner is null until control is shown.
      Loaded += GridWithRulerxaml_Loaded;

    }

    void GridWithRulerxaml_Loaded(object sender, RoutedEventArgs e)
    {
      var adornerLayer = AdornerLayer.GetAdornerLayer(this);
      var rulerAdorner = new RulerAdorner(this);
      adornerLayer.Add(rulerAdorner);
    }
  }
}

最后是装饰器本身:

using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfApplication1
{
  public class RulerAdorner : Adorner
  {
    private FrameworkElement element;
    public RulerAdorner(UIElement el) : base(el)
    {
      element = el as FrameworkElement;
    }

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
    {
      base.OnRender(drawingContext);

      double height = element.ActualHeight;
      double width = element.ActualWidth;

      double linesHorizontal = height/50;
      double linesVertical = width/50;

      var pen = new Pen(Brushes.RoyalBlue, 2) { StartLineCap = PenLineCap.Triangle, EndLineCap = PenLineCap.Triangle };

      int offset = 0;

      for (int i = 0; i <= linesVertical; ++i)
      {
        offset = offset + 50;
        drawingContext.DrawLine(pen, new Point(offset, 0), new Point(offset, height));
      }

      offset = 0;

      for (int i = 0; i <= linesHorizontal; ++i)
      {
        offset = offset + 50;
        drawingContext.DrawLine(pen, new Point(0, offset), new Point(width, offset));
      }
    }
  }
}

如果您希望我详细说明代码本身,请告诉我。

我确认这将在您的主页上的任何内容之上绘制一个网格。您仍然应该能够与下面的内容进行交互。

于 2013-09-11T00:56:15.677 回答
1

您可以使用绑定来“绑定”彼此Canvas的大小和大小。Grid因此,当Grid调整大小时,Canvas也会自动进行。

您也可以使用 aConverter来进行绑定,您必须像与边界的距离一样计算和偏移。

在 WPF 中绑定始终是一个好主意,因此请确保您了解其工作原理的基础知识。

无论如何,您始终可以在 Size-Event 的代码隐藏 (C#/VB) 中执行此操作。只需确定一个控件的大小并将其设置为另一个即可。就像获取 Grid 的actualHeight属性并将其设置为画布的height属性一样。

也许这会给你一个想法:http: //blogs.msdn.com/bencon/archive/2006/05/10/594886.aspxhttp://www.switchonthecode.com/tutorials/wpf-tutorial-binding-转换器

于 2009-11-02T09:55:28.170 回答
1

你想做什么?如果您只想将网格线添加到整个网格,您可以通过设置这样的样式来实现。或者,您可以使用Adorner s。它们用于在单独的图层上装饰/装饰元素。装饰器的好处是,尽管它们位于单独的层上,但它们与所装饰的元素保持同步(大小、位置、变换)。

于 2009-11-02T10:14:00.733 回答