我试图让 2 个控件具有相同的高度。我可以只使用 XAML 吗?
如果我做了类似的事情<Canvas Height="{Binding Height, ElementName=AnotherControl}" />
它实际上并没有做任何事情并且高度变为零。输出面板不会抱怨任何绑定错误,因此 AnotherControl.Height 确实存在。我尝试绑定到 ActualHeight 但它也没有做任何事情。
还有什么我错过的吗?
我试图让 2 个控件具有相同的高度。我可以只使用 XAML 吗?
如果我做了类似的事情<Canvas Height="{Binding Height, ElementName=AnotherControl}" />
它实际上并没有做任何事情并且高度变为零。输出面板不会抱怨任何绑定错误,因此 AnotherControl.Height 确实存在。我尝试绑定到 ActualHeight 但它也没有做任何事情。
还有什么我错过的吗?
我的猜测是你AnotherControl
没有明确地给出一个Height
. 不幸的是,在 WinRT 中(与 WPF 不同,但与 Silverlight 相同),ActualWidth
并且ActualHeight
是所谓的“计算属性”。这意味着属性更改事件在更改时不会在内部引发。结果,绑定到它们是不可靠的,并且正如您所注意到的,它不会完全起作用。
旁注:它可能会不时起作用,但这纯粹是因为绑定框架对ActualHeight
.
就目前而言,您不能仅使用 XAML 来执行此操作。您必须ActualControl.SizeChanged
在代码隐藏中处理事件,并显式设置Height
为AnotherControl.ActualHeight
。
正如 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}" />
这个问题很老,但这是我的解决方案。您可以使用此代码
<!--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 设备上对其进行了测试,效果很好。