7

2 つのコントロールを同じ高さにしようとしています。XAML のみで実行できますか?

私が何かをした場合<Canvas Height="{Binding Height, ElementName=AnotherControl}" />、実際には何もせず、高さがゼロになります。[出力] パネルにはバインド エラーが表示されないため、AnotherControl.Height は実際に存在します。ActualHeight にバインドしようとしましたが、何もしません。

他に見逃したことはありますか?

4

3 に答える 3

12

私の推測では、AnotherControl明示的にHeight. 残念ながら、WinRT では (WPF とは異なりますが、Silverlight と同じです)、 "計算されたプロパティ"ActualWidthActualHeight呼ばれるものです。これは、プロパティ変更イベントが変更されたときに内部的に発生しないことを意味します。その結果、それらへのバインディングは信頼できず、お気づきのように、まったく機能しません。

補足: 場合によっては機能する場合もありますが、これは純粋に、バインディング フレームワークが に対して行う get 呼び出しのタイミングによるものActualHeightです。

現状では、XAML のみで行うことはできません。ActualControl.SizeChangedコード ビハインドでイベントを処理し、HeightAnotherControl.ActualHeight明示的に設定する必要があります。

于 2012-10-25T21:38:38.117 に答える
7

Kshitij Mehtaが述べたように、WinRTでのActualHeightとActualWidthへのバインドは信頼できません。ただし、SizeChanged-Eventを使用する必要がないという回避策があります。

このクラスを追加します。

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"));
        }
    }
}

リソースに配置します。

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

そして、そのプロパティにバインドします。

<TextBlock x:Name="tb1" Text="{Binding ActualWidthValue, ElementName=proxy}"  />
于 2012-10-25T21:58:43.810 に答える
2

この質問は非常に古いですが、これが私の解決策です。このコードを使用できます

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

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

Windows / Windows Phone 8.1 デバイスでテストしたところ、問題なく動作しました。

于 2014-08-20T18:58:05.333 に答える