ลองนึกภาพผู้ออกแบบฟอร์มที่มีการซ้อนทับตารางซึ่งจะแสดงพิกัดบนระนาบ ฉันกำลังพยายามผูกคุณสมบัติของตารางซ้อนทับกับ Canvas
ภายใน ItemsControl
ที่กำหนดเอง
ตารางถูกสร้างขึ้นโดยใช้ VisualBrush
Viewbox
และ Viewport
ของ VisualBrush
ถูกผูกไว้กับ Rect
ในโค้ด เช่นเดียวกับ Height
และ Width
ของ 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>
มีความคิดว่าฉันทำอะไรผิดที่นี่ ขอบคุณ.
แก้ไข: บางทีพื้นหลังเพิ่มเติมเล็กน้อยของสิ่งที่ฉันทำอาจทำให้บริบทดีขึ้น ฉันทำงานให้กับบริษัทซอฟต์แวร์การเตรียมภาษี และในปัจจุบัน แผนกแบบฟอร์มของเราสร้างแบบฟอร์มทดแทนโดยใช้มาร์กอัปที่เขียนขึ้นสำหรับผลิตภัณฑ์ของเราเมื่อประมาณล้านปีก่อน การสร้างแบบฟอร์มด้วยวิธีนี้จะยุ่งยากเล็กน้อย ดังนั้นฉันจึงพัฒนา "ตัวออกแบบฟอร์ม" แบบภาพสำหรับพวกเขา ซึ่งจะเหมือนกับ WYSIWYG มากกว่า และแปลเนื้อหาของตัวออกแบบเป็นมาร์กอัป กรมสรรพากรเป็นผู้เชี่ยวชาญจริงๆ เกี่ยวกับทุกสิ่งที่อยู่ในแบบฟอร์มซึ่งตรงกับต้นฉบับ ดังนั้นจึงมีมาตรฐานที่หลวมมากซึ่งสามารถวาง "การซ้อนทับตาราง" ไว้เหนือแบบฟอร์มเพื่อกำหนดว่าสิ่งต่างๆ ต้องไปในจุดใด โดยพื้นฐานแล้วเป็นระนาบพิกัดอะไรสักอย่าง
FormControl
โดยพื้นฐานแล้วคือการนำเสนอด้วยภาพของหนึ่งในแบบฟอร์มทดแทนเหล่านี้ที่หนึ่งในแบบฟอร์มที่ผู้ออกแบบจะสร้าง
CanvasWidth
และ CanvasHeight
เป็น wrapper CLR ของคุณสมบัติการพึ่งพา ค่าเหล่านี้ถูกกำหนดไว้ใน OnApplyTemplate()
โดยการคูณขนาดของ GridUnitViewbox
ด้วยจำนวนไทล์กริดที่ต้องอยู่ในการซ้อนทับของกริด กล่าวคือ ในกรณีส่วนใหญ่จะเป็นตารางขนาด 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
's Viewbox
และ Viewport
รวมถึงขนาดของ Rectangle
ก่อนที่ฉันจะรวมค่าต่างๆ เข้าด้วยกัน และมันสร้างสิ่งที่มองเห็นออกมาอย่างชัดเจนว่าฉันกำลังทำอะไรอยู่ ฉันยังยืนยันด้วยว่าอันที่จริง 6 และ 11.3266666666667 เป็นค่าสำหรับมิติข้อมูลของ GridUnitViewbox
ระหว่างรันไทม์
ฉันรู้สึกว่าการเชื่อมโยงกำลังสร้าง '0,0,0,0' เนื่องจากการซ้อนทับของกริดเป็นเพียงการแรเงาสีเทาที่กำลังกินทรัพยากรจำนวนมหาศาล จริงๆ แล้วล็อคโปรแกรมถ้าคุณซูมเข้าไป อย่างที่คุณเห็นในโค้ดฉันพยายามเพิ่ม AffectsMeasure
และ AffectsParentMeasure
ลงในตัวเลือก Metadata ของคุณสมบัติการพึ่งพาโดยหวังว่าบางที UI อาจไม่ได้รับการอัปเดตอย่างถูกต้องหลังจากอัปเดตขนาดของ GridUnitViewbox
แล้ว แต่ฉันคิดผิด ฉันไม่แน่ใจว่ามันจะเป็นอะไรอีก