Bayangkan seorang desainer formulir dengan hamparan kisi yang mewakili koordinat pada bidang. Saya mencoba mengikat properti hamparan kisi ke Canvas
dalam ItemsControl
khusus.
Grid dibuat menggunakan VisualBrush
. Viewbox
dan Viewport
VisualBrush
terikat ke Rect
dalam kode, begitu pula Height
dan Width
dari Rectangle
yang digunakan untuk menampilkan petak petak. Namun, saat kontrol ditampilkan, petak petak tampak "sangat kecil" (kisi hanya berwarna abu-abu) sehingga jika saya memperbesar petak, program pada akhirnya akan terhenti, tidak dapat merendernya. Jelas, ini bukanlah efek yang saya inginkan.
<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>
Tahu apa yang saya lakukan salah di sini. Terima kasih.
EDIT: Mungkin sedikit lebih banyak latar belakang tentang apa yang saya lakukan dapat menempatkannya dalam konteks yang lebih baik. Saya bekerja di sebuah perusahaan perangkat lunak persiapan pajak dan, saat ini, divisi formulir kami membuat formulir pengganti menggunakan markup yang ditulis untuk produk kami sekitar satu juta tahun yang lalu. Agak rumit membuat formulir dengan cara ini, jadi saya mengembangkan visual "Perancang Formulir" untuk mereka yang akan lebih mirip WYSIWYG dan menerjemahkan konten desainer ke dalam markup. Ya, IRS benar-benar anal tentang segala sesuatu di formulir yang PERSIS dengan aslinya, jadi ada standar yang sangat longgar di mana "hamparan kotak" dapat ditempatkan di atas formulir untuk menentukan ke mana segala sesuatunya harus pergi; pada dasarnya semacam bidang koordinat.
FormControl
pada dasarnya adalah representasi visual dari salah satu bentuk pengganti yang akan dibuat oleh salah satu desainer bentuk.
CanvasWidth
dan CanvasHeight
adalah pembungkus CLR untuk Properti Ketergantungan. Mereka diberi nilai dalam OnApplyTemplate()
dengan mengalikan dimensi GridUnitViewbox
dengan berapa banyak petak petak yang diperlukan dalam hamparan petak, yaitu. grid 78x63 dalam banyak kasus.
Nama CanvasWidth
dan CanvasHeight
menurut saya mungkin sedikit menyesatkan karena tidak mengacu pada kontrol Canvas
, tetapi pada Grid
yang menampung Canvas
(mungkin perlu mengubah konvensi penamaan). Artinya, CanvasHeight
, CanvasWidth
dan GridUnitViewbox
tidak bergantung pada properti kontrol apa pun, melainkan penghitungan yang dilakukan di 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;
}
}
Kontrol Grid
sebenarnya melakukan apa yang saya inginkan. Ini adalah VisualBrush
dan Rectangle
di dalamnya yang tidak mengikat dengan benar atau tidak diperbarui dengan benar. Komentar tepat di bawah <Grid.Background>
adalah nilai pengujian hard-code yang saya gunakan untuk dimensi VisualBrush
Viewbox
dan Viewport
serta Rectangle
sebelum saya sempat mengikat nilai dan menghasilkan, secara visual, persis seperti yang saya inginkan. Saya juga telah mengonfirmasi bahwa 6 dan 11.3266666666667 sebenarnya adalah nilai untuk dimensi GridUnitViewbox
selama runtime.
Namun saya merasa pengikatannya menghasilkan '0,0,0,0', karena hamparan kisi hanyalah bayangan abu-abu yang menghabiskan banyak sumber daya; sebenarnya mengunci program jika Anda memperbesarnya. Seperti yang Anda lihat, dalam kode saya mencoba menambahkan AffectsMeasure
dan AffectsParentMeasure
ke opsi Metadata properti ketergantungan dengan harapan mungkin UI tidak diperbarui dengan benar setelah dimensi GridUnitViewbox
diperbarui, tetapi saya salah. Saya tidak yakin apa lagi yang bisa terjadi.