我想让两个控件具有相同的高度。我能否只使用XAML实现?
如果我这样做,<Canvas Height="{Binding Height, ElementName=AnotherControl}" />
实际上什么也不会发生,高度变为零。输出面板没有抱怨任何绑定错误,因此AnotherControl.Height确实存在。我尝试将其绑定到ActualHeight,但它也没有作用。
还有其他我可能遗漏的吗?
我想让两个控件具有相同的高度。我能否只使用XAML实现?
如果我这样做,<Canvas Height="{Binding Height, ElementName=AnotherControl}" />
实际上什么也不会发生,高度变为零。输出面板没有抱怨任何绑定错误,因此AnotherControl.Height确实存在。我尝试将其绑定到ActualHeight,但它也没有作用。
还有其他我可能遗漏的吗?
我猜想您的 AnotherControl
没有明确地给出 Height
。 不幸的是,在 WinRT 中(与 WPF 不同,但与 Silverlight 相同),ActualWidth
和 ActualHeight
是所谓的 "计算属性"。 这意味着当它们改变时,没有引发属性更改事件。 结果,对它们进行绑定不可靠,正如您已经注意到的那样,这样做并不能完全起作用。
旁注:这可能在某些时候有效,但纯粹是因为绑定框架调用 ActualHeight
的获取时间。
因此,现在您不能仅使用 XAML 来完成它。 您必须在代码后台中处理 ActualControl.SizeChanged
事件,并将 Height
显式设置为 AnotherControl.ActualHeight
。
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设备上测试过它,效果非常好。