How do I make a WPF data template fill the entire width of the listbox?

后端 未结 8 1352
别跟我提以往
别跟我提以往 2020-12-04 16:23

I have a ListBox DataTemplate in WPF. I want one item to be tight against the left side of the ListBox and another item to be tight ag

相关标签:
8条回答
  • 2020-12-04 16:43

    Ok, here's what you have:

    Column 0: WrapPanel
    Column 1: Nothing
    Column 2: ListBox

    It sounds like you want WrapPanel on the left edge, ListBox on the right edge, and space to take up what's left in the middle.

    Easiest way to do this is actually to use a DockPanel, not a Grid.

    <DockPanel>
        <WrapPanel DockPanel.Dock="Left"></WrapPanel>
        <ListBox DockPanel.Dock="Right"></ListBox>
    </DockPanel>
    

    This should leave empty space between the WrapPanel and the ListBox.

    0 讨论(0)
  • 2020-12-04 16:43

    The method in Taeke's answer forces a horizontal scroll bar. This can be fixed by adding a converter to reduce the grid's width by the width of the vertical scrollbar control.

    using System;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Markup;
    
    namespace Converters
    {
        public class ListBoxItemWidthConverter : MarkupExtension, IValueConverter
        {
            private static ListBoxItemWidthConverter _instance;
    
            #region IValueConverter Members
    
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return System.Convert.ToInt32(value) - SystemParameters.VerticalScrollBarWidth;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
    
            #endregion
    
            public override object ProvideValue(IServiceProvider serviceProvider)
            {
                return _instance ?? (_instance = new ListBoxItemWidthConverter());
            }
        }
    }
    

    Add a namespace to the root node of your XAML.

    xmlns:converters="clr-namespace:Converters"
    

    And update the Grid width to use the converter.

    <Grid.Width>
        <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{converters:ListBoxItemWidthConverter}"/>
    </Grid.Width>
    
    0 讨论(0)
  • 2020-12-04 16:48

    I also had to set:

    HorizontalContentAlignment="Stretch"
    

    on the containing ListBox.

    0 讨论(0)
  • 2020-12-04 16:51
    <Grid.Width>
        <Binding Path="ActualWidth" 
                 RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" />
    </Grid.Width>
    
    0 讨论(0)
  • 2020-12-04 16:55

    Extending Taeke's answer, setting the ScrollViewer.HorizontalScrollBarVisibility="Hidden" for a ListBox allows the child control to take the parent's width and not have the scroll bar show up.

    <ListBox Width="100" ScrollViewer.HorizontalScrollBarVisibility="Hidden">                
        <Label Content="{Binding Path=., Mode=OneWay}" HorizontalContentAlignment="Stretch" Height="30" Margin="-4,0,0,0" BorderThickness="0.5" BorderBrush="Black" FontFamily="Calibri" >
            <Label.Width>
                <Binding Path="Width" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}" />
            </Label.Width>
        </Label>
    </ListBox >
    
    0 讨论(0)
  • 2020-12-04 16:56

    If you want to use a Grid, then you need to change your ColumnDefinitions to be:

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
    

    If you don't need to use a Grid, then you could use a DockPanel:

        <DockPanel>
            <WrapPanel DockPanel.Dock="Left">
                <!--Some content here-->
                <TextBlock Text="{Binding Path=LastName}" TextWrapping="Wrap" FontSize="24"/>
                <TextBlock Text=", " TextWrapping="Wrap" FontSize="24"/>
                <TextBlock Text="{Binding Path=FirstName}" TextWrapping="Wrap" FontSize="24"/>
            </WrapPanel>
            <ListBox DockPanel.Dock="Right" ItemsSource="{Binding Path=PhoneNumbers}" 
     Margin="8,0" Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
            <TextBlock />
        </DockPanel>
    

    Notice the TextBlock at the end. Any control with no "DockPanel.Dock" defined will fill the remaining space.

    0 讨论(0)
提交回复
热议问题