Search code examples
silverlightsilverlight-4.0printingmeasure

Silverlight Measure Method not working properly depending of databound object?


UPDATE II Problem was solved. Thank you.


For a simple Silverlight printing preview engine, my XAML looks like this (excerpt):

<Grid>
   <TextBlock Text="{Binding IntroText}" />
    <ItemsControl ItemsSource="{Binding DataItems}"
                    x:Name="DataItemsControl">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"
                            TextWrapping="Wrap"
                            Margin="0,2" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    <TextBlock Text="{Binding OutroText}" />
</Grid>

I want to ensure that everything fits on a page, therefore i have a simple method:

public bool FitsOnPrintPage(Size pageDimensions)
{
    Measure(new Size(pageDimensions.Width, Double.PositiveInfinity));

    return
        DesiredSize.Height <= pageDimensions.Height &&
        DesiredSize.Width <= pageDimensions.Width;
}

Now we have a strange problem here which I can't explain:

The bound collection DataItems is a generic object List. When containing simple strings, the Measure(...) method works as expected and returns a properly calculated DesiredSize. So far, everything is working.

However, when having a simple object like this...

public class DataItem
{
    public string Value1 { get; set; }
    public string Value2 { get; set; }
}

...and changing the TextBlock Binding to <TextBlock Text="{Binding Path=Value1}"... the resulting view is identical, however the Measure(...) method doesn't return the expected values, the height of the Items is always zero. Also not working: keep Text Binding and override DataItems ToString() method. View working, Measure doesn't.

I was then trying to force a recalculation using methods like InvalidateMeasure() or UpdateLayout() on the DataTemplate or the whole page, without success.

Can you explain this?

UPDATE
Interesting: I've attached a simple custom ValueConverter to the TextBlock's Binding just for debugging reasons. When a string object is bound, I can see that Measure(...) is triggering the Binding - it's resolved first (i can see the debugger stepping into the ValueConverter) and measured afterwards. But when binding a custom class as described above, Measure(...) doesn't touch the Binding, i am stepping into the ValueConverters breakpoint "later". (Have to find out, when exactly)

Does this help you in any kind?


Solution

  • Solved

    the problem was that the page controls were created and calculated first, and added to the displaying control after generation, because i wanted to avoid frequent UI updates. Something similar was even suggested by Ai_boy, who was trying to solve the problem by using an independent Grid Control - unfortunately this turned out as a misleading approach. Only after the generated page control was added to the visual tree, it automatically resolves the Bindings resulting in a proper size measuring.

    Hope this helps anyone.