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

后端 未结 8 1353
别跟我提以往
别跟我提以往 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:57

    The Grid should by default take up the whole width of the ListBox because the default ItemsPanel for it is a VirtualizingStackPanel. I'm assuming that you have not changed ListBox.ItemsPanel.

    Perhaps if you got rid of the middle ColumnDefinition (the others are default "*"), and put HorizontalAlignment="Left" on your WrapPanel and HorizontalAlignment="Right" on the ListBox for phone numbers. You may have to alter that ListBox a bit to get the phone numbers even more right-aligned, such as creating a DataTemplate for them.

    0 讨论(0)
  • 2020-12-04 17:03

    Taeke's answer works well, and as per vancutterromney's answer you can disable the horizontal scrollbar to get rid of the annoying size mismatch. However, if you do want the best of both worlds--to remove the scrollbar when it is not needed, but have it automatically enabled when the ListBox becomes too small, you can use the following converter:

    /// <summary>
    /// Value converter that adjusts the value of a double according to min and max limiting values, as well as an offset. These values are set by object configuration, handled in XAML resource definition.
    /// </summary>
    [ValueConversion(typeof(double), typeof(double))]
    public sealed class DoubleLimiterConverter : IValueConverter
    {
        /// <summary>
        /// Minimum value, if set. If not set, there is no minimum limit.
        /// </summary>
        public double? Min { get; set; }
    
        /// <summary>
        /// Maximum value, if set. If not set, there is no minimum limit.
        /// </summary>
        public double? Max { get; set; }
    
        /// <summary>
        /// Offset value to be applied after the limiting is done.
        /// </summary>
        public double Offset { get; set; }
    
        public static double _defaultFailureValue = 0;
    
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || !(value is double))
                return _defaultFailureValue;
    
            double dValue = (double)value;
            double minimum = Min.HasValue ? Min.Value : double.NegativeInfinity;
            double maximum = Max.HasValue ? Max.Value : double.PositiveInfinity;
            double retVal = dValue.LimitToRange(minimum, maximum) + Offset;
            return retVal;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Then define it in XAML according to the desired max/min values, as well an offset to deal with that annoying 2-pixel size mismatch as mentioned in the other answers:

    <ListBox.Resources>
        <con:DoubleLimiterConverter x:Key="conDoubleLimiter" Min="450" Offset="-2"/>
    </ListBox.Resources>
    

    Then use the converter in the Width binding:

    <Grid.Width>
        <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{StaticResource conDoubleLimiter}"  />
    </Grid.Width>
    
    0 讨论(0)
提交回复
热议问题