从 XAML 调用时,FrameworkElement 方法不绘制网格 - 但从 Window_loaded 调用
FrameworkElement method does not draw grid when called from from XAML - but does from Window_loaded
我正在用 wpf 重建我的 vb6 应用程序,该应用程序自 2011 年以来一直运行良好。
我的应用程序处理 11 个文档。在 vb6 中,我在 MDI 中使用了 11 种形式。
在 wpf 中,我使用的是 Canvas,我称之为 Hold。此 canvas 包含我称为 Doc 的 FrameworkElement 的 11 个实例。
Doc 有为我称为 Cell 的 class 绘制形状和文本的方法。
为了在Doc中放置单元格,需要Doc绘制一个网格。为此,我有一个布尔字段 (bool _showGrid;) if true Doc 绘制网格。
我的问题是 Doc FrameworkElement 在从 xaml 调用时不绘制网格。但是从 Window_Loaded 开始。
这是 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);
}
这是 xaml 在 showGrid 中创建 Doc 的 documentsReceipt 实例设置为 true 不起作用:
<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>
这是我从 Window_Loaded
中省略 documentReceipt=true
时的应用程序
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//documentsReceipt.showGrid = true;
}
Window without grid
这是我启用 showGrid 时的输出
Window with grid
通常你实现这样的控件有点不同。首先,您需要一个依赖项 属性 才能使 ShowGrid
可绑定。接下来是你覆盖 OnRender
来绘制你的形状(或任何东西)。下面是控件的完整实现:
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));
}
}
}
}
我正在用 wpf 重建我的 vb6 应用程序,该应用程序自 2011 年以来一直运行良好。 我的应用程序处理 11 个文档。在 vb6 中,我在 MDI 中使用了 11 种形式。
在 wpf 中,我使用的是 Canvas,我称之为 Hold。此 canvas 包含我称为 Doc 的 FrameworkElement 的 11 个实例。
Doc 有为我称为 Cell 的 class 绘制形状和文本的方法。 为了在Doc中放置单元格,需要Doc绘制一个网格。为此,我有一个布尔字段 (bool _showGrid;) if true Doc 绘制网格。
我的问题是 Doc FrameworkElement 在从 xaml 调用时不绘制网格。但是从 Window_Loaded 开始。
这是 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);
}
这是 xaml 在 showGrid 中创建 Doc 的 documentsReceipt 实例设置为 true 不起作用:
<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>
这是我从 Window_Loaded
documentReceipt=true
时的应用程序
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//documentsReceipt.showGrid = true;
}
Window without grid
这是我启用 showGrid 时的输出 Window with grid
通常你实现这样的控件有点不同。首先,您需要一个依赖项 属性 才能使 ShowGrid
可绑定。接下来是你覆盖 OnRender
来绘制你的形状(或任何东西)。下面是控件的完整实现:
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));
}
}
}
}