Я признаю, что это популярный вопрос, но я не смог найти ничего, что точно ответило бы на него, но я извиняюсь, если что-то пропустил в моих поисках.
Я пытаюсь создать, а затем измеритьэлемент управления во время выполнения с использованием следующего кода (измерения будут использоваться для прокрутки элементов управления в стиле выделения - каждый элемент управления имеет свой размер):
Label lb = new Label();
lb.DataContext= task;
Style style = (Style)FindResource("taskStyle");
lb.Style = style;
cnvMain.Children.Insert(0,lb);
width = lb.RenderSize.Width;
width = lb.ActualWidth;
width = lb.Width;
Код создает элемент управления Label и применяет стильк этому.Стиль содержит мой шаблон управления, который привязывается к объекту «задача».Когда я создаю элемент, он выглядит идеально, однако, когда я пытаюсь измерить элемент управления, используя любое из указанных выше свойств, я получаю следующие результаты (я прохожу и проверяю каждое свойство по очереди):
lb.Width = NaN
lb.RenderSize.Width = 0
lb.ActualWidth = 0
IsЕсть ли способ получить визуализированную высоту и ширину создаваемого вами элемента управления во время выполнения?
ОБНОВЛЕНИЕ:
Извините, что отменили выбор решений в качестве ответов.Они работают на базовом примере системы, которую я настроил, но, похоже, не с моим полным решением.
Я думаю, что это может быть связано со стилем, извините за беспорядок, но я вставляю всевещь здесь.
Во-первых, ресурсы:
<Storyboard x:Key="mouseOverGlowLeave">
<DoubleAnimation From="8" To="0" Duration="0:0:1" BeginTime="0:0:2" Storyboard.TargetProperty="GlowSize" Storyboard.TargetName="Glow"/>
</Storyboard>
<Storyboard x:Key="mouseOverTextLeave">
<ColorAnimation From="{StaticResource buttonLitColour}" To="Gray" Duration="0:0:3" Storyboard.TargetProperty="Color" Storyboard.TargetName="ForeColour"/>
</Storyboard>
<Color x:Key="buttonLitColour" R="30" G="144" B="255" A="255" />
<Storyboard x:Key="mouseOverText">
<ColorAnimation From="Gray" To="{StaticResource buttonLitColour}" Duration="0:0:1" Storyboard.TargetProperty="Color" Storyboard.TargetName="ForeColour"/>
</Storyboard>
И сам стиль:
<Style x:Key="taskStyle" TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Canvas x:Name="cnvCanvas">
<Border Margin="4" BorderBrush="Black" BorderThickness="3" CornerRadius="16">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="1" Color="SteelBlue"/>
<GradientStop Offset="0" Color="dodgerBlue"/>
</LinearGradientBrush>
</Border.Background>
<DockPanel Margin="8">
<DockPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="corbel"/>
<Setter Property="FontSize" Value="40"/>
</Style>
</DockPanel.Resources>
<TextBlock VerticalAlignment="Center" Margin="4" Text="{Binding Path=Priority}"/>
<DockPanel DockPanel.Dock="Bottom">
<Border Margin="4" BorderBrush="SteelBlue" BorderThickness="1" CornerRadius="4">
<TextBlock Margin="4" DockPanel.Dock="Right" Text="{Binding Path=Estimate}"/>
</Border>
<Border Margin="4" BorderBrush="SteelBlue" BorderThickness="1" CornerRadius="4">
<TextBlock Margin="4" DockPanel.Dock="Left" Text="{Binding Path=Due}"/>
</Border>
</DockPanel>
<DockPanel DockPanel.Dock="Top">
<Border Margin="4" BorderBrush="SteelBlue" BorderThickness="1" CornerRadius="4">
<TextBlock Margin="4" Foreground="LightGray" DockPanel.Dock="Left" Text="{Binding Path=List}"/>
</Border>
<Border Margin="4" BorderBrush="SteelBlue" BorderThickness="1" CornerRadius="4">
<TextBlock Margin="4" Foreground="White" DockPanel.Dock="Left" Text="{Binding Path=Name}"/>
</Border>
</DockPanel>
</DockPanel>
</Border>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Кроме того, код, который я использую:
Label lb = new Label(); //the element I'm styling and adding
lb.DataContext= task; //set the data context to a custom class
Style style = (Style)FindResource("taskStyle"); //find the above style
lb.Style = style;
cnvMain.Children.Insert(0,lb); //add the style to my canvas at the top, so other overlays work
lb.UpdateLayout(); //attempt a full layout update - didn't work
Dispatcher.Invoke(DispatcherPriority.Render, new Action(() =>
{
//Synchronize on control rendering
double width = lb.RenderSize.Width;
width = lb.ActualWidth;
width = lb.Width;
})); //this didn't work either
lb.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); //nor did this
double testHeight = lb.DesiredSize.Height;
double testWidth = lb.RenderSize.Width; //nor did this
width2 = lb.ActualWidth; //or this
width2 = lb.Width; //or this
//positioning for my marquee code - position off-screen to start with
Canvas.SetTop(lb, 20);
Canvas.SetTop(lb, -999);
//tried it here too, still didn't work
lb.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
testHeight = lb.DesiredSize.Height;
//add my newly-created label to a list which I access later to operate the marquee
taskElements.AddLast(lb);
//still didn't work
lb.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
testHeight = lb.DesiredSize.Height;
//tried a mass-measure to see if that would work - it didn't
foreach (UIElement element in taskElements)
{
element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
}
Каждый раз, когда вызывается любой из них, значение возвращается либо как 0, либо не как число, но когда метка отображается, она явно имеет размер, который виден.Я пытался запустить этот код с помощью нажатия кнопки, когда на экране видна метка, но это дает те же результаты.
Это из-за стиля, который я использую?Возможно, данные?То, что я сделал неправильно, ослепительно очевидно, или гремлины WPF просто действительно ненавидят меня?
Второе обновление:
После дальнейшего поиска яобнаружил, что Measure () относится только к исходному размеру элемента.Если шаблон элемента управления изменяет это путем фактического добавления элементов управления, то, вероятно, лучшим методом будет измерение каждого из них, но я признаю, что это более чем грязно.
Компилятор должен иметь какой-то способ измерения всего содержимого элемента управления, так как он должен использовать его для размещения элементов, например, в стек-панелях.Должен быть какой-то способ получить к нему доступ, но сейчас у меня совершенно нет идей.