1

I'm trying to data bind a TextBlock to the RenderSize of a Rectangle. Here is the code.

<StackPanel x:Name="root">
        <Rectangle x:Name="rect" Fill="Green" RenderTransformOrigin="0.5,0.5" Height="100" Width="100" />

        <TextBlock Text="{Binding ElementName=rect, Path=Width}"></TextBlock>
        <TextBlock Text="{Binding ElementName=rect, Path=ActualWidth}"></TextBlock>
        <TextBlock Text="{Binding ElementName=rect, Path=RenderSize}"></TextBlock>
        <Slider Value="{Binding ElementName=rect, Path=Width, Mode=TwoWay}" Maximum="200"></Slider>
        <Button Content="Manually Get RenderSize" Click="Button_Click_1"></Button>
        <TextBlock x:Name="info"></TextBlock>
    </StackPanel>

When I move the slider, rect become larger, and the first TextBox is updated correctly. However, ActualWidth and RenderSize stay to 0, and 0,0.

When I click on Button, I get the RenderSize programmatically and show it in the last TextBlock, which is different than 0,0.

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    info.Text = rect.RenderSize.ToString();
}

So my binding on the RenderSize does not update the TextBox correctly... Why ? Thanks for your help,

Nicolas Dorier
  • 7,383
  • 11
  • 58
  • 71
  • I wrote an answer to a similar question here: https://stackoverflow.com/questions/1602148/binding-to-actualwidth-does-not-work/1604662#1604662 It should be useful to you. – KeithMahoney Jan 04 '10 at 20:18
  • again another hack in silverlight, it starts to make me mad... – Nicolas Dorier Jan 04 '10 at 20:21
  • it might be easier if you just handle the SizeChanged event on the element and update the value as appropriate in the event handler. The solution described in the post I linked to is only necessary if you must use data-binding. – KeithMahoney Jan 04 '10 at 20:47

1 Answers1

3

RenderSize is not dependency property, but it corresponds to dependency properties (ActualWidth, ActualHeight)

So to bind to RenderSize we can use MultiBinding to (ActualWidth, ActualHeight)

<TextBlock>
  <TextBlock.Text>
    <MultiBinding Converter="{x:Static MyConv:SizePartsToSizeConverter.Instance}">
                    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
                    <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

public class SizePartsToSizeConverter:IMultiValueConverter
{
    private static SizePartsToSizeConverter m_instance = new SizePartsToSizeConverter();
    public static SizePartsToSizeConverter Instance { get { return m_instance; } }

    public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
    {
        var values = value.Where(x => x is Double).Cast<double>().ToList();
        if (values.Count()!=2) return DependencyProperty.UnsetValue;

        return new Size(values[0],values[1]);
    }

    public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
nicolas2008
  • 945
  • 9
  • 11