'de çalışma zamanında oluşturulan kontroller Bu popüler bir sorudur, ancak tam olarak cevap veren bir şey bulamadım, ancak aramalarımda bir şey özlediysem özür dilerim. Ben oluşturmak ve sonra aşağıdaki kodu kullanarak çalışma zamanında bir kontrol ölçümü için çalışıyorumWPF
(ölçümler daha sonra tarzı marquee için denetimleri kaydırma kullanılacaktır - Her bir kontrol farklı bir boyutudur):
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;
Kod, bir Etiket denetimi oluşturur ve ona bir stil uygular. Stil, "görev" nesnesine bağlanan kontrol şablonumu içerir.
lb.Width = NaN
lb.RenderSize.Width = 0
lb.ActualWidth = 0
var mı uygulanıyor: Ben öğesi oluşturduğunuzda ben şu sonuçları (I gezinmek ve sırayla her özelliği incelemek) olsun yukarıdaki Ben özelliklerden herhangi birini kullanarak kontrolünü ölçmek için deneyin ancak zaman mükemmel görünür Çalışma zamanında oluşturduğunuz bir kontrolün oluşturulmuş yüksekliğini ve genişliğini elde etmenin yolu nedir?
GÜNCELLEME: cevaplar olarak çözümlerinizi kaldırarak için
üzgünüm. Kurduğum basit bir örnek sistem üzerinde çalışıyorlar ama tam çözümümle değil.
Sanırım bu tarzla ilgili bir şey olabilir, bu karışıklık için çok üzüldüm, ama burada tüm şeyi yapıştırıyorum.
Birincisi, kaynaklar:
<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>
Ve stil kendisi:
<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>
Ayrıca, kod kullanıyorum:
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));
}
herhangi Her zaman Bu denir, değer ya 0 olarak döndürülür veya bir sayı değil, henüz etiket oluşturulduğunda görünür olduğu gibi bir boyutu vardır. Etiketi ekranda göründüğünde, ancak bu aynı sonuçları üreten bir tuşa basarak bu kodu çalıştırmayı denedim.
Kullanmakta olduğum stil yüzünden mi? Databindings belki? Yaptığım şey yanlış bir şekilde açık mıdır yoksa WPF Gremlinler sadece gerçekten benden nefret mi ediyor?
İkinci Güncelleme: O ölçün (keşfettim
ayrıca arama yaptıktan sonra) sadece orijinal eleman boyuta uygulanır. Bir denetim şablonu, gerçekten denetimleri ekleyerek bunu değiştirirse, en iyi yöntem muhtemelen her birini ölçmek olur, ancak itiraf etmeliyim ki bu biraz dağınıklıktan daha fazlasıdır.
Derleyicinin, örneğin, yığın panelleri içine yerleştirmek için kullanması gerektiğinden, bir denetleyicinin tüm içeriğini ölçmenin bir yolu olmalıdır. Ona erişmenin bir yolu olmalı, ama şimdilik tamamen fikirlerden çıktım.
Bu kodu nereden kullanıyorsunuz? Pencerenin yapıcısında mı? Eğer öyleyse, kontroller oluşturuluncaya kadar beklemeniz gerekir. – Carlo