2014-08-29 24 views

回答

1

我們最終作出一個靜態函數

// Ensure block does not have MAXLINES or text trimming set prior to checking 
    public static bool IsTruncated(TextBlock block, int maxLines) 
    { 
     if (block == null) 
     { 
      throw new ArgumentNullException("block"); 
     } 

     //the cut-off height is the height at which text will be cut off in the UI 
     var cutOffHeight = maxLines * block.LineHeight; 

     //determine whether the actual height of the TextBlock is greater than the cut-off height 
     return block.ActualHeight > cutOffHeight; 
    } 

關鍵是要確保MAXLINES和文字修整未在正文塊運行此功能之前設置。此函數返回後,即設置Maxlines時。在我的情況下,我只是將返回的布爾值保存在一個包含對象中,所以我知道它更長。然後我設置maxlines和另一個按鈕來查看基於該布爾值的擴展內容。

+1

小心解釋爲什麼我的解決方案無法正常工作?恕我直言,我的更好。 – 2014-09-12 00:18:29

+0

我沒有說你的沒有工作。我剛剛發佈了我們實際使用的解決方案。除了我們的解決方案更短之外,我們正在避免數據綁定這是主要問題。我感謝你的回答,我們多次提出了這個答案。 – 2014-09-12 16:03:15

5

老方法 - 當TextWrapping設置爲無

要知道,如果一個TextBlock修剪,我們可訂閱SizeChanged事件及其ActualWidthMaxWidth你指定的比較。要獲得TextBlock正確ActualWidth,我們需要將TextTrimming保留爲其默認值(即TextTrimming.None),並將其設置爲在寬度超過時將其修剪。

新途徑 - 當TextWrapping設置爲Wrap

現在,我知道是因爲TextWrapping設置爲Wrap,並承擔VirticalAlignment未指定(默認爲Stretch),該Width將始終保持不變。當TextBlock的實際高度超過其父項的高度時,我們只需要監視SizeChanged事件。我們使用Behavior來封裝上面的所有邏輯。這裏需要提到的是一個static輔助類有很多附屬屬性,或者從TextBlock繼承的新控件可以做同樣的事情;但作爲一個大混合風扇,我更喜歡儘可能使用Behaviors

的行爲

public class TextBlockAutoTrimBehavior : DependencyObject, IBehavior 
{ 
    public bool IsTrimmed 
    { 
     get { return (bool)GetValue(IsTrimmedProperty); } 
     set { SetValue(IsTrimmedProperty, value); } 
    } 

    public static readonly DependencyProperty IsTrimmedProperty = 
     DependencyProperty.Register("IsTrimmed", typeof(bool), typeof(TextBlockAutoTrimBehavior), new PropertyMetadata(false)); 

    public DependencyObject AssociatedObject { get; set; } 

    public void Attach(DependencyObject associatedObject) 
    { 
     this.AssociatedObject = associatedObject; 
     var textBlock = (TextBlock)this.AssociatedObject; 

     // subscribe to the SizeChanged event so we will know when the Width of the TextBlock goes over the MaxWidth 
     textBlock.SizeChanged += TextBlock_SizeChanged; 
    } 

    private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     // ignore the first time height change 
     if (e.PreviousSize.Height != 0) 
     { 
      var textBlock = (TextBlock)sender; 

      // notify the IsTrimmed dp so your viewmodel property will be notified via data binding 
      this.IsTrimmed = true; 
      // unsubscribe the event as we don't need it anymore 
      textBlock.SizeChanged -= TextBlock_SizeChanged; 

      // then we trim the TextBlock 
      textBlock.TextTrimming = TextTrimming.WordEllipsis; 
     } 
    } 

    public void Detach() 
    { 
     var textBlock = (TextBlock)this.AssociatedObject; 
     textBlock.SizeChanged += TextBlock_SizeChanged; 
    } 
} 

的XAML

<Grid HorizontalAlignment="Center" Height="73" VerticalAlignment="Center" Width="200" Background="#FFD2A6A6" Margin="628,329,538,366"> 
    <TextBlock x:Name="MyTextBlock" TextWrapping="Wrap" Text="test" FontSize="29.333"> 
     <Interactivity:Interaction.Behaviors> 
      <local:TextBlockAutoTrimBehavior IsTrimmed="{Binding IsTrimmedInVm}" /> 
     </Interactivity:Interaction.Behaviors> 
    </TextBlock> 
</Grid> 

注意,Behavior暴露一個依賴屬性IsTrimmed,你可以在你的視圖模型的數據綁定到一個屬性(即IsTrimmedInVm在這種情況下)。

P.S. WinRT中沒有FormattedText函數,否則實現可能有點不同。

+0

寬度是否也考慮高度?這意味着如果我的寬度爲100的框是2行高,那麼文本的寬度是200? – 2014-09-08 17:52:38

+0

哦,如果是這樣的話,那就更簡單了。其實我們不再需要'MaxWidth'。由於'TextBlock'橫向和縱向拉伸,其寬度將保持不變。只有超過父母身高時,身高才會改變。因此,我們所需要做的就是聽取SizeChanged事件並在高度結束時執行操作。我已經更新了「行爲」,並在xaml中添加了「TextWrapping」。它現在應該適用於任何行數。 – 2014-09-09 00:51:13

相關問題