在Silverlight 3.0应用程序中,我试图在画布中创建一个矩形,并将其拉伸到画布的整个宽度。我尝试通过绑定到父容器的ActualWidth属性(如下面的示例),但是当我看不到任何绑定错误时,该值没有被绑定。矩形不可见,因为它的宽度为零。此外,尝试绑定到包含我的矩形的画布的ActualWidth,但这没有任何区别。
我做了find this bug logged on Microsoft Connect,但没有列出任何解决方法。
编辑:原始代码示例不正确我正在尝试实现,更新为更清晰。
<UserControl> <Border BorderBrush="White" BorderThickness="1" CornerRadius="4" HorizontalAlignment="Center"> <Grid x:Name="GridContainer"> <Rectangle Fill="Aqua" Width="150" Height="400" /> <Canvas> <Rectangle Width="{Binding Path=ActualWidth,ElementName=GridContainer}" Height="30" Fill="Red" /> </Canvas> <StackPanel> <!-- other elements here --> </StackPanel> </Grid> </Border> </UserControl>
解决方法
你想做什么需要你将数据绑定到ActualWidth属性?
这是Silverlight的一个已知问题,并没有简单的解决方法。
这是Silverlight的一个已知问题,并没有简单的解决方法。
可以做的一件事是设置视觉树,使您不需要实际设置Rectangle的宽度,并允许其拉伸到适当的大小。所以在上面的例子中,如果你删除了Canvas(或者将Canvas改为其他Panel),并将Rectangle的HorizontalAlignment设置为Stretch,它将占用所有可用的宽度(实际上是Grid的宽度)。
但是,在您的具体情况下可能无法实现,并且可能需要设置数据绑定。已经确定这是不可能直接的,但是在代理对象的帮助下,我们可以设置所需的绑定。考虑这个代码:
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")); } } }
我们可以在xaml中使用它,如下所示:
<Grid x:Name="LayoutRoot"> <Grid.Resources> <c:ActualSizePropertyProxy Element="{Binding ElementName=LayoutRoot}" x:Name="proxy" /> </Grid.Resources> <TextBlock x:Name="tb1" Text="{Binding ActualWidthValue,ElementName=proxy}" /> </Grid>
所以我们将Binding TextBlock.Text绑定到代理对象上的ActualWidthValue。代理对象又提供了由另一个绑定提供的元素的ActualWidth。
这不是问题的简单解决方案,但是我可以想到如何将数据绑定到ActualWidth是最好的。
如果您更多地解释了您的方案,可能会提出一个更简单的解决方案。完全不需要DataBinding;是否可以从SizeChanged事件处理程序中的代码设置属性?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。