Получите отрендеренный размер UserControl на холсте - PullRequest
1 голос
/ 29 декабря 2011

Мне нужно добавить несколько пользовательских элементов управления в Canvas.Размер UserControl зависит от количества элементов, присутствующих в ItemsControl из UserControl.Чтобы правильно расположить элементы управления и нарисовать соединительные линии между пользовательскими элементами управления, мне нужна абсолютная ширина / высота относительно родительского холста.Как получить это?ActualHeight и ActualWidth возвращают 0.

Я задавал аналогичный вопрос ранее, но не смог получить правильный ответ.

РЕДАКТИРОВАТЬ: Добавление XAML od UserControl

<UserControl x:Class="SilverlightApplication2.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"   
DataContext="{Binding RelativeSource={RelativeSource Self}}" Loaded="UserControl_Loaded">

<Grid x:Name="LayoutRoot" Background="White">
    <Border CornerRadius="3" BorderThickness="1" BorderBrush="LightGray">
        <Grid  Name="grid1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
            <Grid.RowDefinitions>
                <RowDefinition Height="40*" />
                <RowDefinition Height="136*" />
            </Grid.RowDefinitions>
            ...
            <Grid Name="gridPC" Grid.Row="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="55*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="55*" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>            
                ....

                <ItemsControl x:Name="pitems" ItemsSource="{Binding RowsP}" Grid.Row="1">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Width="250" Orientation="Horizontal">
                                <TextBlock Text="{Binding X}" Width="100" />
                                <TextBlock Text="{Binding Y}" Width="130" />
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

               ......
            </Grid>
        </Grid>
    </Border>
</Grid>

Ответы [ 5 ]

2 голосов
/ 29 декабря 2011

У вас есть несколько опций, которые вы можете сделать, заставив вызвать Window.Measure и Window.Arrange сделает все значения для вычисления, или вы можете получить эти значения в событии Window.Loaded.Эта же проблема уже обсуждалась по этому вопросу .

Если вы определяете размер содержимого:

window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
window.Arrange(new Rect(0, 0, window.DesiredWidth, window.DesiredHeight));

Если вы используете явный размер окна:

window.Measure(new Size(Width, Height));
window.Arrange(new Rect(0, 0, window.DesiredWidth, window.DesiredHeight));

или

public MyWindow()
{
    Loaded += delegate
    {
        // access ActualWidth and ActualHeight here
    };

}
1 голос
/ 29 декабря 2011

Я активно создаю элемент управления временной шкалы Silverlight, и я не делаю измерения, как советовали предыдущие авторы. Я просто жду окончательного вызова onsize или другого события OnChanged зависимых свойств.

Вот что я делаю, чтобы загрузить свой элемент управления с холстом:

  1. Подписаться на событие Loaded пользовательского элемента управления (, которое является целью для всех вызовов зависимых событий загрузки и события size в (шаг # 2) ).
  2. Подписаться на событие изменения размера (которое вызывает событие загрузки элементов управления, как указано в # 1).
  3. Все зависимые свойства OnXXXPropertyChanged событие вызывает OnLoad (# 1).
  4. В загруженном событии я проверяю, чтобы установить this.ActualWidth (не ноль), а также действительность всех моих зависимых свойств. (Если все они не установлены, а мой логический глобальный флаг указывает, что он еще не загружен; он ничего не делает и завершает работу (ожидание следующего вызова).
  5. Как только мое событие загрузки обнаруживает, что все зависимые свойства были установлены, и ActualWidth не равен нулю, он начинает процесс использования ширины и зависимых свойств, чтобы начать создавать мои субэлементы управления.

НТН

1 голос
/ 29 декабря 2011

ActualWidth и ActualHeight работают только после визуализации элемента управления.

Чтобы получить желаемый размер элемента управления, вам нужно дать ему возможность измерить себя, вызвав его метод Measure. После этого вы можете использовать свойство DesiredSize, которое будет содержать искомые значения.

Есть также хорошая статья Чарльза Петцольда, описывающая подобную ситуацию:

Мышление вне сетки

1 голос
/ 29 декабря 2011

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

Это в первую очередь потому, что система разметки в WPF выполняется в два прохода: мера и проход аранжировки.Сначала контейнерный элемент управления (в вашем случае Panel) запрашивает размер дочерних элементов после завершения этого прохода, контейнер упорядочивает дочерние элементы, используя размеры, рассчитанные в проходе меры.

Я бы порекомендовал прочитать эту статью MSDN, посвященную разделу Измерение и расположение детей.http://msdn.microsoft.com/en-us/library/ms745058.aspx

Дайте мне знать, если это не поможет, и я потрачу еще немного времени, чтобы освежить мою память на все детали.

На основании ваших правок вы можете проверитьэтот пост, описывающий, как создавать объекты, связанные линиями.http://denisvuyka.wordpress.com/2007/10/21/wpf-diagramming-drawing-a-connection-line-between-two-elements-with-mouse/

Я думаю, что это больше направлено на ваш точный сценарий.

0 голосов
/ 10 апреля 2014

Использование Canvas-Panel вместо Grid-Panel в корневом элементе и доступ к ActualWidth в Loaded обработчике событий должны работать довольно хорошо.Эта статья помогла http://msdn.microsoft.com/en-us/library/ms745058.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...