2011-09-28 9 views
0

탄성의 WrapPanel을 만들고자합니다. 새 열이 패널 내부에 들어갈 때까지 각 열이 패널의 너비에 맞게 늘어납니다.탄성의 WrapPanel과 TextTrimming

너비는 ItemMinWidth를 기반으로합니다.

패널을 만들 수 있었지만 TextBlock을 넣고 TextTrimming을 CharacterEllipsis로 설정하면 문제가 생길 수 있습니다. 내 패널에서는 작동하지 않습니다. 3 개의 점은 나타나지 않습니다. 열의 너비가 작동하는 것처럼 보이지만 내용이 너비로 무한대를받는 것처럼 보입니다. 여기

내 패널입니다 :

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Windows; 
using System.Windows.Controls; 

namespace WrapPanelTest 
{ 
    public class ElasticWrapPanel : Panel 
    { 
     #region Constructor 

     public ElasticWrapPanel() 
     { 
     } 

     #endregion 

     #region Properties 

     [TypeConverter(typeof(LengthConverter))] 
     public double ItemMinWidth 
     { 
      get 
      { 
       return (double)GetValue(ItemMinWidthProperty); 
      } 
      set 
      { 
       SetValue(ItemMinWidthProperty, value); 
      } 
     } 

     public static readonly DependencyProperty ItemMinWidthProperty = DependencyProperty.Register("ItemMinWidth", typeof(double), typeof(ElasticWrapPanel)); 

     [TypeConverter(typeof(LengthConverter))] 
     public double ColumnWidth 
     { 
      get 
      { 
       return (double)GetValue(ColumnWidthProperty); 
      } 
      private set 
      { 
       SetValue(ColumnWidthProperty, value); 
      } 
     } 

     public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register("ColumnWidth", typeof(double), typeof(ElasticWrapPanel)); 

     #endregion 

     #region Protected methods 

     protected override Size MeasureOverride(Size availableSize) 
     { 
      _uiElementsRect.Clear(); 
      _columnCount = CalculateColumnCount(availableSize); 

      if (_columnCount > 0) 
      { 
       ColumnWidth = (int)Math.Floor(availableSize.Width/_columnCount); 
       double rowHeight = 0; 
       double lastRowHeight = 0; 
       int currentColumn = 0; 
       int currentRow = 0; 

       foreach (UIElement children in InternalChildren) 
       { 
        children.Measure(availableSize); 

        rowHeight = Math.Max(rowHeight, children.DesiredSize.Height); 

        Rect childrenRect = new Rect(0, 0, 0, 0); 
        childrenRect.X = currentColumn * ColumnWidth; 
        childrenRect.Y = lastRowHeight; 
        childrenRect.Width = ColumnWidth; 
        childrenRect.Height = children.DesiredSize.Height; 

        _uiElementsRect.Add(children, childrenRect); 

        currentColumn++; 

        if (currentColumn == _columnCount) 
        { 
         lastRowHeight += rowHeight; 
         currentRow++; 
         rowHeight = 0; 
         currentColumn = 0; 
        } 
       } 
      } 

      if (_uiElementsRect.Any()) 
      { 
       double maxBottom = _uiElementsRect.Max(ui => ui.Value.Bottom); 

       return new Size(availableSize.Width, maxBottom); 
      } 
      else 
       return base.MeasureOverride(availableSize); 
     } 

     protected override Size ArrangeOverride(Size finalSize) 
     { 
      if (_columnCount > 0) 
       foreach (KeyValuePair<UIElement, Rect> keyValuePair in _uiElementsRect) 
        keyValuePair.Key.Arrange(keyValuePair.Value); 

      return base.ArrangeOverride(finalSize); 
     } 

     #endregion 

     #region Private methods 

     private int CalculateColumnCount(Size availableSize) 
     { 
      if (ItemMinWidth == 0 || Double.IsNaN(ItemMinWidth) || Double.IsInfinity(availableSize.Width)) 
       return 0; 
      else 
       return (int)Math.Floor(availableSize.Width/ItemMinWidth); 
     } 

     #endregion 

     #region Private members 

     int _columnCount = 0; 

     IDictionary<UIElement, Rect> _uiElementsRect = new Dictionary<UIElement, Rect>(); 

     #endregion 
    } 
} 

그리고 여기 TextTrimming 작동하는 WrapPanel에 비해 exemple의 : 3 점 말미에

<Window x:Class="WrapPanelTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WrapPanelTest" 
     Title="MainWindow" 
     Height="480" 
     Width="640"> 

    <Window.Resources> 

     <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}"> 
      <Setter Property="Text" Value="Lorem ipsum dolor sit amet, consectetur adipiscing elit."/> 
      <Setter Property="TextTrimming" Value="CharacterEllipsis"/> 
      <Setter Property="Margin" Value="1"/> 
      <Setter Property="Background" Value="Silver"/> 
     </Style> 

    </Window.Resources> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <WrapPanel ItemWidth="200"> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
     </WrapPanel> 

     <local:ElasticWrapPanel ItemMinWidth="200" Grid.Row="1"> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
      <TextBlock Style="{StaticResource TextBlockStyle}"/> 
     </local:ElasticWrapPanel> 

    </Grid> 
</Window> 

당신은 WrapPanel에서 그것을 볼 수 내 요소에는 없지만 내 요소에는 없습니다.

답변

1

TextBlocks에는 크기 세트가 없으므로 원하는만큼 늘릴 수 있습니다.

는 다른 방법으로 당신의 MeasureOverride 방법으로 크기를 제한하는 것을 고려

foreach (UIElement children in InternalChildren) 
{ 
    children.Measure(availableSize); 

    ((FrameworkElement)children).MaxWidth = ColumnWidth; 

    // Other code 
}