微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

silverlight – 绑定到ActualWidth不起作用

在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的一个已知问题,并没有简单的解决方法

可以做的一件事是设置视觉树,使您不需要实际设置Rectangle的宽度,并允许其拉伸到适当的大小。所以在上面的例子中,如果你删除了Canvas(或者将Canvas改为其他Panel),并将Rectangle的Horizo​​ntalAlignment设置为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] 举报,一经查实,本站将立刻删除。

相关推荐