Как определить ширину визуального элемента в WPF? - CodeHelper

Как определить ширину визуального элемента в WPF?

1

Только ленивому неизвестно, что в WPF настоятельно не рекомендуется жестко прописывать ширину и высоту у визуальных элементов. В связи с чем упомянутые ширина и высота определяются динамически в зависимости от элементов, вложенных в данный. И, как можно заметить, в таком случае frameworkElement.Width = NaN.

Но вот столкнулся с задачей, когда элемент нужно разместить на экране по координатам, зависящим от ширины этого элемента. Как это сделать?

Новые ответы


0

Не, я не в конструкторе пробовал.

FrameworkElement source = (FrameworkElement) message.Source.UIElement;
Popup popup = source.FindName<Popup>("popupErrors", true);

ItemsControl list = popup.FindName<ItemsControl>("errorsList", true);
list.ItemsSource = _validationResults;

var sourceOffset = source.TransformToVisual(Application.Current.MainWindow).Transform(new Point(0, 0));
var popupOffset = popup.TransformToVisual(Application.Current.MainWindow).Transform(new Point(0, 0));

popup.IsOpen = true;

popup.HorizontalOffset = sourceOffset.X - popupOffset.X - popup.ActualWidth;

popup.Child.MouseLeave += delegate { popup.IsOpen = false; };
safonovea

Возможно та же причина. Попробуй рассмотреть методы Measure(), MeasureCore() и UpdateLayout() класса UIElement. Может они помогут решить проблему.

0

Не умещается в комментарий, поэтому ответом сделаю :)

Насколько я понимаю, значение свойства FrameworkElement.ActualWidth вычисляется непосредственно после прохождения отрисовки. Если попытаться получить значение в конструкторе (т.е. на этапе создания, еще до отрисовки элемента), то это значение справедливо будет равно значению по-умолчанию, т.е. 0.

Пример:

Window1.xaml:

<Window x:Class="WpfApplication2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBox x:Name="tbxButtonText" Grid.Row="0" />
        <Button Grid.Row="1" Content="Get width" Click="ButtonBase_OnClick" />
    </Grid>
</Window>

Window1.xaml.cs:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        MessageBox.Show(string.Format("Width: {0}; Height: {1}", tbxButtonText.ActualWidth, tbxButtonText.ActualHeight));
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(string.Format("Width: {0}; Height: {1}", tbxButtonText.ActualWidth, tbxButtonText.ActualHeight));
    }
}

При запуске, еще до отрисовки окна будет показан MessageBox, в нем значения высоты и ширины будут нулевые. После отрисовки окна, при клике на кнопку ширина и высота будут показывать верные значения.

0

Небольшой кусочек кода может пролить свет на эту темную историю :) Один из возможных вариантов — попытка получить значение ActualWidth в конструкторе, когда ширина еще не вычислена.

Alexander

Не понял. Почему в конструкторе? Почему, когда длина еще не вычислена?

0

В общем, NaN - это значение по-умолчанию для Width и в данном случае может интерпретироваться как "не установлено". Width - это "желаемая" ширина FrameworkElement'а, в то время как ActualWidth - ширина элемента, определяемая при отрисовке этого элемента (т.о. доступна только для чтения). Рекомендуется ориентироваться на нее.

Но тут у меня опять проблема - она равна 0.0 почему-то... Хотя визуально элемент виден.


v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.