Свойство зависимости WPF изменено. ActualWidth == 0

Как заставить Window измерить его элементы управления в конструкторе, чтобы значения ActualWidth а также ActualHeight не ноль? Вот пример, демонстрирующий мою проблему (я пытался вызвать функции Measure и Arrange, но, возможно, неправильно).

XAML:

<Window x:Class="WpfApplication7.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStartupLocation="CenterScreen"
        Title="WPF Diagram Designer"
        Background="#303030"
        Height="600" Width="880" x:Name="Root">

  <Grid x:Name="LayoutRoot">
        <DockPanel>
            <TextBox DockPanel.Dock="Top" Text="{Binding ElementName=Root, Mode=TwoWay, Path=Count}"/>
            <Button DockPanel.Dock="Top" Content="XXX"/>
            <Canvas x:Name="MainCanvas">

            </Canvas>
        </DockPanel>
    </Grid>
</Window>

код позади:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System;
using System.Windows.Media;

namespace WpfApplication7
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
            Arrange(new Rect(DesiredSize));
            Count = 6;
        }

        public static readonly DependencyProperty CountProperty = DependencyProperty.Register("Count",
            typeof(int), typeof(Window1), new FrameworkPropertyMetadata(5, CountChanged, CoerceCount));

        private static object CoerceCount(DependencyObject d, object baseValue)
        {
            if ((int)baseValue < 2) baseValue = 2;
            return baseValue;
        }

        public int Count
        {
            get { return (int)GetValue(CountProperty); }
            set { SetValue(CountProperty, value); }
        }

        private static void CountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window1 w = d as Window1;
            if (w == null) return;
            Canvas c = w.MainCanvas;
            if (c == null || c.Children == null) return;
            c.Children.Clear();
            if (c.ActualWidth == 0) MessageBox.Show("XXX");
            for (int i = 0; i < w.Count; i++)
                c.Children.Add(new Line()
                {
                    X1 = c.ActualWidth * i / (w.Count - 1),
                    X2 = c.ActualWidth * i / (w.Count - 1),
                    Y1 = 0,
                    Y2 = c.ActualHeight,
                    Stroke = Brushes.Red,
                    StrokeThickness = 2.0
                });
        }
    }
}

Смысл этого примера - нарисовать количество вертикальных линий от левого края до правого края. Это хорошо работает, когда я изменяю значение в TextBox, однако я хочу, чтобы линии уже были нарисованы в начале.

Итак, как мне обновить код, чтобы нарисовать линии в начале уже, пожалуйста? Или другой подход, чем упомянутый код, будет более подходящим для достижения этой цели?

Спасибо за любые усилия.

1 ответ

Решение

Возможно, вы могли бы поставить логику в OnContentRendered,

Окна Content к тому времени все должно быть ActualWidth и т. д. должен быть готов.

Пример:

protected override void OnContentRendered(EventArgs e)
{
    base.OnContentRendered(e);

    // Logic
}
Другие вопросы по тегам