2009-11-08 16 views
35

Böyle tanımlanan bir Canvas içinde bir Grid var:Neden bu durumda ActualWidth ve ActualHeight 0.0 vardır?

<Canvas x:Name="outerCanvas"> 
    <Grid Grid.Row="1" Name="cGrid" ShowGridLines="True" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}" Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition /> 
      <RowDefinition /> 
     </Grid.RowDefinitions> 
     <Rectangle Name="rectangle1" Stroke="Black" Fill="AntiqueWhite" /> 
     <Rectangle Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="1" Name="rectangle2" Stroke="Black" Fill="AliceBlue" /> 
     <Rectangle Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="1" Grid.RowSpan="1" Name="rectangle3" Stroke="Black" Fill="Aqua" /> 
     <Rectangle Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Grid.RowSpan="1" Name="rectangle4" Stroke="Black" Fill="DarkViolet" /> 
    </Grid> 
</Canvas> 

Benim problem, Pencere yapıcı, sonra InitializeComponents() ya Grid.ColumnDefinitions[0].ActualWidth veya "herhangi dikdörtgen". ActualWidth'un tümü 0,0'a ayarlanır (yüksekliklerin aynısı). Bu bilgiyi almak için ne yapacağımı anlayamıyorum. herhangi bir yardım?

Gözlemler:

  1. Ben dış tuval genişliği ve yüksekliği tanımlamasını değilim ama eğer yaparsam, benim sorunu çözmek does't. Öyle içindeki her dikdörtgen ActualWidth s vardır ve ActualHeight s
  2. ızgaranın genişlik/yükseklik tuval bağlı ama bu bağlayıcı ve sorunumu çıkarmadan çalıştı, bu Canvas/Grid tüm pencere alanını işgal görebilirsiniz Çalışma zamanında
  3. Bu kontrol, ölçülen ve yerleşene kadar

cevap

69

ActualHeight ve ActualWidth ayarlanmamıştır devam etti. Genellikle InitializeComponent()'da bir ölçüme neden olan hiçbir şey yoktur, bu yüzden geri döndüğünde bunlar hala sıfır olacaktır.

Pencerenin InitializeComponent() döndürdüğünden sonra pencerenin Measure() ve Arrange() yöntemlerini manuel olarak çağırarak daha önce hesaplanacak şekilde bunları zorlayabilirsiniz.

sen içeriğe boyutlandırma ediyorsanız:

window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height)); 

Eğer açık bir pencere boyutunu kullanıyorsanız:

window.Measure(new Size(Width, Height)); 
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height)); 
+1

Teşekkürler! Sadece küçük bir düzeltme: window.Measure void döndürür. DesiredWidth/DesiredHeight özelliklerini değiştirir :) Ama senin fikrin doğru. –

+1

Bu, API'leri iki kez kontrol etmeden kafanızın üst kısmından kod yazdığınızda böyle olur. Düzeltme için teşekkürler. MeasureOverride boyutu döndürür, ancak Measure sadece onları depolar. Cevap düzeltildi. –

+11

"DesiredWidth" önce çalışır, ancak .NET'in daha yeni sürümleri DesiredSize.Width ve DesiredSize kullanın emin değilim.Yükseklik –

52

Ray bu gerçeği nedeniyle olduğunu (1) doğru olduğundan emin Ölçme ve düzenleme işlemi henüz yapılmadı. Kontrol ActualXxx özelliklerini erişmeden önce yüklenene kadar Ancak, (pahalı) Başka bir düzen geçmek zorlamak yerine, sadece bekleyebilir:

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

} 
+2

Kabul. Yüklenmeyi beklemek, daha iyi bir yaklaşım olan IMHO'dur. –

+0

Teşekkürler! Sadece meraklı ... Pencerede neden bir OnLoaded yöntemi yok? –

+3

Yüklenmeyi Beklemek iyi bir fikirdir (+1) ve çoğu durumda çalışacaktır. Ancak hiçbir zaman bir PresentationSource'a bağlanmadığınız zaman (yani pencereyi asla göstermediğiniz), Loaded'in hiçbir zaman çağrılmayacağını unutmayın. Örneğin, bir sayfaya bir denetim ekleyip eklememeye karar verirken, bununla daha önce karşılaştım. Bu yüzden Loaded kullanmanın mümkün olduğunda daha iyi olduğunu ve tüm vakaları kapsadığını söyleyebilirim, aksi takdirde Measure/Edit (Düzenleme/Düzenleme) daha iyidir. Bununla birlikte, vakaların% 90'ında en iyi uygulama, ActualWidth/ActualHeight'tan tamamen uzak kalmak olacaktır. (örneğin, daha/daha iyi paneller, yükseklik/genişliğe bağlanma, MeasureOverride) –

-7

ActualWidth ve ActualHeight yüklemeden önce, XAML yükleme tamamlandıktan sonra kullanılabilir nasıl size can Bu parametreleri bulmak?

Yüklenen olayı kullanın ve iç kısımda ActualWidth ve ActualHeight bulabilirsiniz. Herkes ActualWidth ve ActualHeight bile tamamlar Loaded sonra Yani sadece bir memuru kod sarılmış ve aşağıdaki gibi Yüklü öncelik ayarlamak denilen olsun gerektiğini söyledi olarak Bizim durumumuzda

private void me_Loaded(object sender, RoutedEventArgs e) 
{ 
    // do your stuffs here. 
} 
+6

, Kent – kenny

+0

konseptinden alınan yanıtın aynısıdır. –

-1

çözüm basitti:

Dispatcher.Invoke(new Action(() => 
{ 
    graphHeight = ActualHeight; 
    graphWidth = ActualWidth; 
}), DispatcherPriority.Loaded); 
İlgili konular