想象一个带有网格覆盖的表单设计器,它可以表示平面上的坐标。我正在尝试将网格覆盖的属性绑定到自定义Canvas
中的ItemsControl
。
使用VisualBrush
创建网格。 VisualBrush
的{{1}}和Viewbox
绑定到代码中的Viewport
,以及Rect
和Height
{ {1}}用于显示网格图块。但是,当控件显示时,网格图块似乎“无限小”(网格只是灰色),如果我放大网格,程序最终会抓住,无法渲染它。显然,这不是我想要的效果。
Width
知道我在这里做错了什么。感谢。
编辑: 也许我正在做的更多背景可能会把它放在更好的背景下。我在一家税务准备软件公司工作,目前,我们的表格部门使用一百万年前为我们的产品编写的标记创建替代表格。以这种方式创建表单有点麻烦,所以我正在为他们开发一个视觉“表单设计器”,它更像是一个WYSIWYG,并将设计器的内容翻译成标记。好吧,美国国税局对于表格上的所有内容都是真实的肛门,因为有一个非常宽松的标准,可以在表格上放置一个“网格叠加”来确定需要去的地方;基本上是各种坐标平面。
Rectangle
本质上是其中一种替代形式的视觉表现形式,其中一种形式是设计师创造的。
<Style TargetType="{x:Type Controls:FormControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:FormControl}">
<Border Background="White"
BorderBrush="Black"
BorderThickness="1"
Padding="49">
<Grid Height="{TemplateBinding CanvasHeight}"
Width="{TemplateBinding CanvasWidth}">
<Grid.Background>
<!--"0,0,6,11.3266666666667"-->
<VisualBrush TileMode="Tile"
Viewbox="{TemplateBinding GridUnitViewbox}"
ViewboxUnits="Absolute"
Viewport="{TemplateBinding GridUnitViewbox}"
ViewportUnits="Absolute">
<VisualBrush.Visual>
<Rectangle Height="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox.Height}"
HorizontalAlignment="Left"
Opacity="{TemplateBinding GridOpacity}"
Stroke="Black"
StrokeThickness=".1"
VerticalAlignment="Top"
Width="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox.Width}" />
</VisualBrush.Visual>
</VisualBrush>
</Grid.Background>
<ItemsPresenter />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="Controls:FormControlItem">
<Setter Property="Canvas.Left"
Value="{Binding Path=X}" />
<Setter Property="Canvas.Top"
Value="{Binding Path=Y}" />
</Style>
</Setter.Value>
</Setter>
</Style>
和FormControl
是依赖项属性的CLR包装器。通过将CanvasWidth
的维度乘以网格覆盖中需要的许多网格图块,即CanvasHeight
,为OnApplyTemplate()
分配值。在大多数情况下,78x63网格。
我认为名称GridUnitViewbox
和CanvasWidth
可能有点误导,因为他们没有引用CanvasHeight
控件,而是引用Canvas
Grid
{1}}(可能需要更改命名约定)。也就是说,Canvas
,CanvasHeight
和CanvasWidth
不依赖于任何控件的属性,而是依赖于GridUnitViewbox
中的计算。
OnApplyTemplate()
public static readonly DependencyProperty GridUnitViewboxProperty =
DependencyProperty.Register("GridUnitViewbox", typeof(Rect), typeof(FormControl),
new FrameworkPropertyMetadata(new Rect(0, 0, 6, 11.3266666666667),
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsParentMeasure));
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
FormattedText formattedText = new FormattedText(
"X",
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("Courier New"),
10,
Brushes.Black);
this.GridUnitViewbox = new Rect(0, 0, formattedText.WidthIncludingTrailingWhitespace, formattedText.Height);
if (this.PageLayout == PageLayoutType.Landscape)
{
this.CanvasHeight = this.GridUnitViewbox.Height * 48.0;
this.CanvasWidth = this.GridUnitViewbox.Width * 109.0;
}
if (this.PageLayout == PageLayoutType.Portrait)
{
this.CanvasHeight = this.GridUnitViewbox.Height * 63.0;
this.CanvasWidth = this.GridUnitViewbox.Width * 78.0;
}
}
控件实际上正在完成我想要它做的事情。它内的Grid
和VisualBrush
要么没有正确绑定,要么没有正确更新。 Rectangle
下面的评论是我用于<Grid.Background>
的{{1}}和VisualBrush
以及Viewbox
维度的硬编码测试值在我开始约束价值之前,它在视觉上准确地产生了我想要的东西。我还确认6和11.3266666666667实际上是运行期间Viewport
维度的值。
我感觉绑定正在产生'0,0,0,0'但是,因为网格覆盖只是一个灰色阴影,占用了大量的资源;事实上,如果你放大它,就会锁定程序。正如您所看到的,在代码中我尝试将Rectangle
和GridUnitViewbox
添加到依赖项属性的元数据选项中,希望在AffectsMeasure
的维度之后UI可能没有正确更新更新了,但我错了。我不确定它还能是什么。
答案 0 :(得分:1)
好吧,为了防止其他人遇到类似的问题,我找到了解决方法。显然VisualBrush
对TemplateBinding
有点挑剔。我这样调整了XAML并解决了问题:
<VisualBrush TileMode="Tile"
Viewbox="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox}"
ViewboxUnits="Absolute"
Viewport="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox}"
ViewportUnits="Absolute">
以下是我从中获取信息的article。
答案 1 :(得分:0)
什么是CanvasWidth和CanvasHeight?它们是否定义了?
另外,我认为除非明确指定,否则画布没有大小。绑定到它时,宽度/高度可能为零。
在渲染过程之后尝试使用ActualWidth和ActualHeight或画布来查看它们是否包含任何值,但是除非您提供一个值,否则它们不会。