2011-03-11 27 views
1

UPDATE II 問題是solved。謝謝。根據數據綁定對象,Silverlight度量方法無法正常工作?


對於一個簡單的Silverlight打印預覽引擎,我的XAML看起來像這樣(節選):

<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> 

我想確保一切都適合一個頁面上,所以我有一個簡單的方法:

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

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

現在我們這裏有一個奇怪的問題,我無法解釋:

在b ound collection DataItems是一個通用的object列表。包含簡單字符串時,Measure(...)方法按預期工作,並返回正確計算的DesiredSize。到目前爲止,一切工作都正常。

然而,具有簡單對象像這樣...

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

當...和改變的TextBlock綁定到<TextBlock Text="{Binding Path=Value1}"...所得視圖相同,但是Measure(...)方法不返回預期值,項目的高度總是爲零。也不工作:保持文本綁定並覆蓋DataItem s ToString()方法。查看工作,措施不。

我當時試圖在DataTemplate或整個頁面上使用類似InvalidateMeasure()UpdateLayout()的方法強制重新計算,但沒有成功。

你能解釋一下嗎?

UPDATE
有趣:我已經附上簡單的自定義ValueConverter到TextBlock的只是爲了調試原因約束力。當綁定一個string對象時,我可以看到Measure(...)正在觸發綁定 - 它首先被解析(我可以看到調試器進入ValueConverter),然後進行測量。但是,如上所述綁定自定義類時,Measure(...)不會觸及綁定,我將在「稍後」步驟中進入ValueConverter的斷點。 (必須確定時間)

這對你有幫助嗎?

回答

0

解決

的問題是,頁面控件創建和計算第一,並添加到生成後的顯示控制,因爲我想避免頻繁的UI更新。類似的事情甚至是suggested by Ai_boy,誰試圖通過使用獨立的Grid控制解決問題 - 不幸的是,這是一個誤導性的方法。只有在生成的頁面控件添加到可視化樹後,它纔會自動解析綁定,從而產生適當的大小測量。

希望這可以幫助任何人。

0

答案很簡單..你在「Silverlight的方式」

在Silverligth工作沒有 - 忽略了最低馬瑟如果字符串以適應屏幕寬度與否,如果串這麼想的配合,只是設置TextBlock.WrapWrap ...

你有這個問題,因爲'舊的思維方式'...

但如果你要這麼多試試這個:

var ContainerGrid = new Grid(); // create grid at runtime 

// !!! it's important for controlToMesure.Parent property to be NULL, if it's not 
// !!! then temporary remove controlToMesure from parent container... 
ContainerGrid.Children.Add(controlToMesure); // add control that you want to mesure 

ContainerGrid.Measure(new Size(pageWidth, pageHeight)); 
ContainerGrid.Arrange(new Rect(0, 0, pageWidth, pageHeight)); 
ContainerGrid.UpdateLayout(); 

var size = ((FrameworkElement)ContainerGrid.Children[0]).DesiredSize; 
+0

謝謝!不幸的是,它不起作用,我甚至暫時從它的父節點中刪除'controlToMesure',如上所述。對於每個測試項目,大小的高度爲4 - 這是純邊緣高度(2 Top + 2 Bottom)。雖然綁定字符串仍然措施正確,我想我可能有一個「時間」的問題在這裏與數據綁定..? – thmshd 2011-03-11 14:15:41

+0

好吧,可能有很多原因..我可以從我的個人expiriense說 - 如果你嘗試做一些不是'Silverlight方式'的東西,你會得到很多錯誤.. – 2011-03-11 15:06:08

+0

並嘗試改變這個'測量(新尺寸(pageDimensions.Width,Double.PositiveInfinity));'這個'Measure(新尺寸(pageDimensions.Width,pageDimensions.Height));' – 2011-03-11 15:08:24

0

這裏是http://silverpdf.codeplex.com/

梅比它的代碼會幫助你,但你必須修改它,使其可用。

private System.Windows.Size CalculeteSize() 
{ 
    var s = new System.Windows.Controls.StackPanel() 
    { 
    VerticalAlignment = System.Windows.VerticalAlignment.Center, 
    HorizontalAlignment = System.Windows.HorizontalAlignment.Center 
    }; 
    var fs = FontPool.GetFontStream(Typeface.FontFamily.Source); 
    s.Children.Add(new System.Windows.Controls.TextBlock 
    { 
    Text = Text, 
    FontSource = new FontSource(fs), 
    FontSize = EmSize, 
    FontFamily = Typeface.FontFamily, 
    FontStretch = Typeface.FontStretch, 
    FontStyle = Typeface.FontStyle, 
    FontWeight = Typeface.FontWeight, 
    }); 
    s.Measure(new System.Windows.Size(double.MaxValue, double.MaxValue)); 

    var aw = s.DesiredSize.Width; 
    var ah = s.DesiredSize.Height; 
    var size = new System.Windows.Size(aw, ah); 

    return size; 
} 
+0

好的方法,但我需要在這裏有TextBlock的文本值,但我沒有,它必須綁定到DataContext對象...好的,你可以說我可以以編程方式添加綁定表達式,而不是設置文本 - 正確。但是我擔心我會產生同樣的效果 - 綁定不會很早就解決。此外,使用更高級的數據模板將會變得糟糕 - 該主題僅描述了一個基本階段。 – thmshd 2011-03-11 22:36:05

相關問題