Метод FrameworkElement не рисует сетку при вызове из XAML, но делает это из Window_loaded

Я перестраиваю в wpf свое приложение vb6, которое отлично работает с 2011 года. Мое приложение обрабатывает 11 документов. В vb6 я использовал 11 форм в MDI.

В wpf я использую Canvas, который я назвал Hold. Этот холст содержит 11 экземпляров FrameworkElement, который я назвал Doc.

В Doc есть методы рисования формы и текста для класса, который я назвал Cell. Для того, чтобы разместить ячейки в Доке, В Доке нужно нарисовать сетку. Для этого у меня есть логическое поле (bool _showGrid;), если 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, в котором экземпляр DocumentReceipt Doc создается в showGrid, для которого установлено значение 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>

Это приложение, когда я пропускаю documentReceipt=true из Window_Loaded

private void Window_Loaded(object sender, RoutedEventArgs e)
{
   //documentsReceipt.showGrid = true;
}

Окно без сетки

И это результат, когда я включаю showGrid Окно с сеткой


person Ben Youcef    schedule 25.12.2016    source источник


Ответы (1)


Обычно вы реализуете такой элемент управления немного по-другому. Прежде всего, вам нужно свойство зависимости, чтобы 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));
            }
        }
    }
}
person gomi42    schedule 25.12.2016