想象一下具有網格疊加的表單設計器,它將表示平面上的座標。我試圖將自定義ItemsControl
中的網格疊加層的屬性綁定到Canvas
。自定義控件TemplateBinding問題
網格使用VisualBrush
創建。 VisualBrush
的Viewbox
和Viewport
在代碼中綁定到Rect
,以及Rectangle
的Height
和Width
用於顯示網格圖塊。然而,當控件顯示時,網格貼片似乎是「無限小」(網格只是灰色),因爲如果我放大網格,程序最終會抓住,無法呈現它。顯然,這不是我要去的效果。
<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
實質上是這些替代形式之一的可視化表示形式,即設計師將要創建的形式之一。
CanvasWidth
和CanvasHeight
是依賴屬性的CLR包裝。通過乘以GridUnitViewbox
的尺寸,他們在OnApplyTemplate()
中被分配值,然而許多網格瓦片需要在網格覆蓋中,即,大多數情況下爲78x63格。
名稱CanvasWidth
和CanvasHeight
我想可能是他們不指Canvas
控制有點誤導,但對Grid
容納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>
正下方的註釋是我在使用VisualBrush
的Viewbox
和Viewport
以及Rectangle
的尺寸之前對其進行的硬編碼測試值,它在視覺上確切地說明了我要做的事情。我也確認了6和11.3266666666667實際上是運行期間GridUnitViewbox
尺寸的值。
但我有一種感覺,即綁定產生'0,0,0,0',但是,因爲網格覆蓋只是一個灰色陰影,正在消耗大量的資源;實際上,如果您放大該程序,就會鎖定該程序。如您所見,在代碼中,我嘗試將AffectsMeasure
和AffectsParentMeasure
添加到依賴項屬性的元數據選項中,希望在更新GridUnitViewbox
的維度後UI可能沒有正確更新,但我錯了。我不知道還有什麼可以的。
你需要更具體,並打破你的問題。人們懷疑是否會花時間去瀏覽大量的XAML標記。 – 2011-03-11 05:36:20