2012-10-25 29 views
6

2 kontrolün aynı yüksekliğe sahip olmasına çalışıyorum. Sadece XAML ile yapabilir miyim?Kontrol yüksekliğini başka bir kontrolün yüksekliğine nasıl aktarabilirim?

<Canvas Height="{Binding Height, ElementName=AnotherControl}" /> gibi bir şey yapsaydım, aslında hiçbir şey yapmaz ve yükseklik sıfıra gider. Çıkış paneli, herhangi bir bağlama hataları hakkında şikayet etmez, bu yüzden bir AnotherControl.Height gerçekten var. ActualHeight'a bağlanmayı denedim ama hiçbir şey yapmıyor.

Özlediğim başka bir şey var mı?

+0

@Clemens ile aynı yorum, WinRT XAML kullanıyorsanız, WPF etiketinizi kaldırmanız gerekir –

cevap

10

Tahminimce, AnotherControl numaralı telefona açıkça Height verilmemektedir. Ne yazık ki, WinRT'de (WPF'den farklı olarak, ancak Silverlight ile aynı), ActualWidth ve ActualHeight "hesaplanan özellikler" olarak bilinir. Bu, bir özellik değiştirilen olayın, değiştiklerinde dahili olarak yükseltilmemesi anlamına gelir. Sonuç olarak, onlara bağlanma güvenilir değildir ve fark ettiğiniz gibi oldukça işe yaramaz.

Yan not: Zaman zaman işe yarayabilir, ancak bunun nedeni, bağlanma çerçevesinin zamanlama nedeniyle ActualHeight yapmasıdır.

Bu nedenle, bunu XAML ile yapamazsınız. Kodun arka tarafında ActualControl.SizeChanged olayını işlemek ve Height'u AnotherControl.ActualHeight'a açıkça ayarlamanız gerekir.

+0

XAML'de yapmak istediğim için motivasyonum, denetimin öğe şablonunun birden çok katmanında olması ve bunun maliyetli olması olabilir. Onları – xster

+0

kodu ile yapın. Bu sadece XAML'de mümkün olsa bile, maliyet aynı olacaktır. Bağlama altyapısı, yapacağınız şeyle aynı şeyi yapar ... Bağımlılık özelliği/INPC özelliğinde değiştirilen bir özellik için kayıt yapar ve daha sonra bağlama kaynağından hedefe giden değeri atar. Bunu sadece kodunda kopyalıyorsun. –

6

Kshitij Mehta'nın belirttiği gibi, WinRT'deki ActualHeight ve ActualWidth öğelerine bağlanma güvenilir değildir. kaynaklarda

public class ActualSizePropertyProxy : FrameworkElement, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public FrameworkElement Element 
    { 
     get { return (FrameworkElement)GetValue(ElementProperty); } 
     set { SetValue(ElementProperty, value); } 
    } 

    public double ActualHeightValue 
    { 
     get { return Element == null ? 0 : Element.ActualHeight; } 
    } 

    public double ActualWidthValue 
    { 
     get { return Element == null ? 0 : Element.ActualWidth; } 
    } 

    public static readonly DependencyProperty ElementProperty = 
     DependencyProperty.Register("Element", typeof(FrameworkElement), typeof(ActualSizePropertyProxy), 
            new PropertyMetadata(null, OnElementPropertyChanged)); 

    private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ((ActualSizePropertyProxy)d).OnElementChanged(e); 
    } 

    private void OnElementChanged(DependencyPropertyChangedEventArgs e) 
    { 
     FrameworkElement oldElement = (FrameworkElement)e.OldValue; 
     FrameworkElement newElement = (FrameworkElement)e.NewValue; 

     newElement.SizeChanged += new SizeChangedEventHandler(Element_SizeChanged); 
     if (oldElement != null) 
     { 
      oldElement.SizeChanged -= new SizeChangedEventHandler(Element_SizeChanged); 
     } 
     NotifyPropChange(); 
    } 

    private void Element_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     NotifyPropChange(); 
    } 

    private void NotifyPropChange() 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("ActualWidthValue")); 
      PropertyChanged(this, new PropertyChangedEventArgs("ActualHeightValue")); 
     } 
    } 
} 

Yeri o:

bu sınıfı ekleyin:

<UserControl.Resources> 
    <c:ActualSizePropertyProxy Element="{Binding ElementName=YourElement}" x:Name="proxy" /> 
</UserControl.Resources> 

Ve bağlama Ama geçici çözüm de, sen sizeChanged-Etkinlik kullanmak zorunda değilsin nerede güzel olduğunu özelliklerine:

<TextBlock x:Name="tb1" Text="{Binding ActualWidthValue, ElementName=proxy}" /> 
1

Bu soru çok eskidir, ama işte benim çözümüm. Sen benim Windows/Windows Phone 8.1 Cihaz üzerinde test ettik bu kod

<!--First Button--> 
<Button x:Name="button1" Height="50" Width="100"/> 

<!--Second Button--> 
<Button x:Name="button2" Height="50" Width="{Binding ElementName=button1, Path=Width}"/> 

kullanabilir ve büyük workes.

İlgili konular