2015-01-16 77 views
0

我正在與WPF一起工作,並在一個問題中堆疊。現在我有ListBoxListBoxItemsPanelStackPanel。當StackPanelOrientationVertical它工作正常!
演示:
enter image description hereWPF:ListBoxItem TextTrimming

XAML代碼:

<Grid> 
     <Grid.Resources> 
      <XmlDataProvider x:Key="xmlData" XPath="/records"> 
       <x:XData> 
        <records xmlns=""> 
         <entry text="Veeeeeeeeeeeeeeeeeeery looooooooooooooooooooooong text"/> 
         <entry text="A little bit shorter text" /> 
         <entry text="Normal text"/> 
        </records> 
       </x:XData> 
      </XmlDataProvider> 
     </Grid.Resources> 
     <ListBox 
      ItemsSource="{Binding Source={StaticResource xmlData}, XPath=entry}" 
      ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 
      <ListBox.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Vertical"></StackPanel> 
       </ItemsPanelTemplate> 
      </ListBox.ItemsPanel> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding [email protected]}" TextTrimming="CharacterEllipsis"/> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </Grid> 

但我需要設置StackPanel Orientation Horizontal。當我設置水平TextBlock文字不修剪。 任何想法來解決這個問題?

謝謝Jamaxack!

回答

1

我創建的自定義Grid 「AutoColumGrid」。 Demo Project

XAML代碼:

<StackPanel> 
     <Button Click="Button_Click">Add</Button> 
     <Button Click="Button_Click_1">Remove</Button> 
     <ListBox Name="uiList" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 
      <ListBox.ItemsPanel> 
       <ItemsPanelTemplate> 
        <local:AutoColumnGrid/> 
       </ItemsPanelTemplate> 
      </ListBox.ItemsPanel> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding}" TextTrimming="CharacterEllipsis"/> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </StackPanel> 

後面的代碼:

 public MainWindow() 
     { 
      InitializeComponent(); 
      Loaded += MainWindow_Loaded; 

     } 

     void MainWindow_Loaded(object sender, RoutedEventArgs e) 
     { 
      uiList.Items.Add("Looooooooooooong text 1"); 
      uiList.Items.Add("Normal text 2"); 
      uiList.Items.Add("Short 3"); 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      uiList.Items.Add("text 4"); 
     } 

     private void Button_Click_1(object sender, RoutedEventArgs e) 
     { 
      if (uiList.Items.Count > 0) 
      { 
       uiList.Items.RemoveAt(0); 
      } 
     } 

自定義網格:

public class AutoColumnGrid : Grid 
{ 
    protected override void OnVisualChildrenChanged(System.Windows.DependencyObject visualAdded, System.Windows.DependencyObject visualRemoved) 
    { 
     //Checking VisualAdded if it is not null than adding child to Grid 
     if (visualAdded != null) 
     { 
      // Getting column definition count 
      int columnDefinitionCount = this.ColumnDefinitions.Count; 
      // Getting child from last, because adds to last 
      var child = this.Children[columnDefinitionCount]; 
      // Adding new ColumnDefinition 
      this.ColumnDefinitions.Add(new ColumnDefinition()); 
      // Setting column to child 
      Grid.SetColumn(child, columnDefinitionCount); 
     }//Checking VisualRemoved if it is not null than child from Grid 
     else if (visualRemoved != null) 
     { 
      int columnDefinitionIndex = Grid.GetColumn(visualRemoved as UIElement); 
      this.ColumnDefinitions.RemoveAt(columnDefinitionIndex); 
     } 

     Application.Current.MainWindow.Dispatcher.BeginInvoke(new Action(SetColumnWidth)); 
    } 

    /// <summary> 
    /// Setts Width to each column 
    /// if Grid content bigger than window than sets width in percent else if Grid content less than window sets to auto 
    /// </summary> 
    private void SetColumnWidth() 
    { 
     for (int index = 0; index < this.ColumnDefinitions.Count; index++) 
     { 
      var gridActualWidth = this.ActualWidth; 
      // Getting Grids width 
      this.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
      var gridDesiredSize = Convert.ToInt16(this.DesiredSize.Width); 
      //calculating nesseseryAreaPercent 
      var nesseseryAreaPercent = gridDesiredSize/gridActualWidth * 100; 
      //setting column index to child 
      var child = this.Children[index]; 
      Grid.SetColumn(child, index); 

      // if nesseseryAreaPercent less or equal 100%, it means grid content is less than grids width and we setting to auto 
      if (nesseseryAreaPercent <= 100) 
      { 
       this.ColumnDefinitions[index].Width = GridLength.Auto; 
      } 
      else 
      { // Else setting with persent 
       child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
       int columnWidth = Convert.ToInt16(child.DesiredSize.Width); 
       this.ColumnDefinitions[index].Width = new GridLength(columnWidth, GridUnitType.Star); 
      } 
     } 
    } 
} 


Thanks Jamshed!

+0

@kmatyaszek這裏我的解決辦法 – Jamaxack

0

你應該設置TextBlock.MaxWidth屬性:

<Grid> 
    <Grid.Resources> 
     <XmlDataProvider x:Key="xmlData" XPath="/records"> 
      <x:XData> 
       <records xmlns=""> 
        <entry text="Veeeeeeeeeeeeeeeeeeery looooooooooooooooooooooong text"/> 
        <entry text="A little bit shorter text" /> 
        <entry text="Normal text"/> 
       </records> 
      </x:XData> 
     </XmlDataProvider> 
    </Grid.Resources> 
    <ListBox 
     ItemsSource="{Binding Source={StaticResource xmlData}, XPath=entry}" 
     ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal"></StackPanel> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock MaxWidth="200" Text="{Binding [email protected]}" TextTrimming="CharacterEllipsis"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

編輯:

爲了達到你的目標,你應該使用MultiValueConverter並設置寬度各TextBlock元素:

XAML:

<Window x:Class="WpfListBoxItemTextTrimming.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" 
     xmlns:local="clr-namespace:WpfListBoxItemTextTrimming"> 
    <Window.Resources> 
     <local:ListBoxWidthConverter x:Key="listBoxWidthConverter"/> 
    </Window.Resources> 
    <Grid> 
     <Grid.Resources> 
      <XmlDataProvider x:Key="xmlData" XPath="/records"> 
       <x:XData> 
        <records xmlns=""> 
         <entry text="Veeeeeeeeeeeeeeeeeeery looooooooooooooooooooooong text"/> 
         <entry text="A little bit shorter text" /> 
         <entry text="Normal text"/> 
        </records> 
       </x:XData> 
      </XmlDataProvider> 
     </Grid.Resources> 
     <ListBox x:Name="LbMBox" 
      ItemsSource="{Binding Source={StaticResource xmlData}, XPath=entry}" 
      ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 
      <ListBox.ItemsPanel> 
       <ItemsPanelTemplate> 
        <VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal"/> 
       </ItemsPanelTemplate> 
      </ListBox.ItemsPanel> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding [email protected]}" TextTrimming="CharacterEllipsis"> 
         <TextBlock.Width> 
          <MultiBinding Converter="{StaticResource listBoxWidthConverter}"> 
           <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" /> 
           <Binding ElementName="LbMBox" Path="Items.Count" /> 
          </MultiBinding> 
         </TextBlock.Width> 
        </TextBlock> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </Grid> 
</Window> 

ListBoxWidthConverter轉換器:

public class ListBoxWidthConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (values != null && values.Length == 2) 
     { 
      var actualWidth = System.Convert.ToDouble(values[0]); 
      var numOfItems = System.Convert.ToInt32(values[1]); 
      return (actualWidth/numOfItems) - 10; 
     } 
     return Binding.DoNothing; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

最大寬度適用於只是第一文本塊,但是當我調整窗口,它是不會改變任何的TextBlocks – Jamaxack

+0

@JamshedAkhmedov再次檢查我的回答:) – kmatyaszek

+0

檢查我的帖子標記爲答案 – Jamaxack

相關問題