I am rebuilding in wpf my vb6 application that is working perfectly since 2011. My app handles 11 documents. In vb6 I used 11 forms in an MDI.
In wpf I am using a Canvas that I called Hold. This canvas holds 11 instances of a FrameworkElement that I called Doc.
Doc has methods for drawing shape and text for a class that I called Cell. In order to place cells in Doc, In need Doc to draw a grid. For that I have a Boolean field (bool _showGrid;) if true Doc draws the grid.
My problem is that Doc FrameworkElement does not draw the grid when called from xaml. But from Window_Loaded it does.
this is a part of the Doc FrameworkElement:
public class Doc : FrameworkElement
{
VisualCollection paper;
DrawingVisual cellMaker;
bool _showGrid;
public Doc()
{
paper = new VisualCollection(this);
//SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
}
public bool showGrid
{
set
{
_showGrid = value;
if (_showGrid)
{
drawGrid();
}
}
}
private void drawGrid()
{
DrawingVisual grid = new DrawingVisual();
using(DrawingContext dc = grid.RenderOpen())
{
for(int i = 0; i <= Width; i += 18)
{
dc.DrawLine(new Pen(Brushes.OrangeRed, 1), new Point(i, 0), new Point(i, Height));
}
for(int j = 0; j <= Height; j += 18)
{
dc.DrawLine(new Pen(Brushes.OrangeRed, 1), new Point(0, j), new Point(Width, j));
}
dc.Close();
}
paper.Add(grid);
}
And this is xaml where documentsReceipt instance of Doc is created in showGrid is set to true witch is not working:
<ScrollViewer Grid.Row="1" Grid.Column="0">
<Canvas Name="Hold" Width="21cm" Height="29.7cm" Background="White" Margin="17">
<dc:Doc Name="documentsReceipt"
Width="{Binding Path=ActualWidth,ElementName=Hold}"
Height="{Binding Path=ActualHeight,ElementName=Hold}"
showGrid="True"
Loaded="documentsReceipt_Loaded">
</dc:Doc>
<TextBox Name="txt"
TextChanged="txt_TextChanged"
KeyDown="txt_KeyDown"
PreviewKeyDown="txt_PreviewKeyDown"/>
</Canvas>
</ScrollViewer>
This is the app with when I omit documentReceipt=true
from Window_Loaded
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//documentsReceipt.showGrid = true;
}
And this is the output when I enable showGrid Window with grid
Usually you implement a control like this a little bit different. First of all you need a dependency property for ShowGrid
to be bindable. Next is you override OnRender
to draw your shapes (or what ever). Here is the full implementation of the control:
public class Doc : FrameworkElement
{
public bool ShowGrid
{
get { return (bool)GetValue (ShowGridProperty); }
set { SetValue (ShowGridProperty, value); }
}
public static readonly DependencyProperty ShowGridProperty =
DependencyProperty.Register ("ShowGrid", typeof (bool), typeof (Doc), new FrameworkPropertyMetadata (false, FrameworkPropertyMetadataOptions.AffectsRender));
protected override void OnRender (DrawingContext dc)
{
if (ShowGrid)
{
for (int i = 0; i <= ActualWidth; i += 18)
{
dc.DrawLine (new Pen (Brushes.OrangeRed, 1), new Point (i, 0), new Point (i, Height));
}
for (int j = 0; j <= ActualHeight; j += 18)
{
dc.DrawLine (new Pen (Brushes.OrangeRed, 1), new Point (0, j), new Point (Width, j));
}
}
}
}