如何让一个WPF数据模板填写列表框的整个宽度?(How do I make a WPF data t

2019-07-04 02:42发布

我有一个ListBox DataTemplate WPF中。 我想一个项目是对左侧紧ListBox和另一个项目是对右侧紧,但我无法弄清楚如何做到这一点。

到目前为止,我有一个Grid有三个栏,左侧和右侧的人有内容和中心是一个占位符,它的宽度设置为“*”。 我要去哪里错了?

下面是代码:

<DataTemplate x:Key="SmallCustomerListItem">
    <Grid HorizontalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <WrapPanel HorizontalAlignment="Stretch" Margin="0">
            <!--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 ItemsSource="{Binding Path=PhoneNumbers}" Grid.Column="2" d:DesignWidth="100" d:DesignHeight="50"
     Margin="8,0" Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False" HorizontalAlignment="Stretch"/>
    </Grid>
</DataTemplate>

Answer 1:

我也不得不设置:

HorizontalContentAlignment="Stretch"

在含ListBox



Answer 2:

<Grid.Width>
    <Binding Path="ActualWidth" 
             RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" />
</Grid.Width>


Answer 3:

好吧,这里就是你拥有的一切:

列0: WrapPanel
第1列:没有
第2列: ListBox

这听起来像你想WrapPanel在左边, ListBox右侧边缘和空间占用什么在中间靠左。

要做到这一点最简单的方法其实是使用DockPanel ,没有一个Grid

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

这应该离开之间的间距WrapPanelListBox



Answer 4:

扩展Taeke的回答,设置ScrollViewer.HorizontalScrollBarVisibility="Hidden"了一个ListBox让孩子控制拿父母的宽度,没有滚动条显示。

<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 >


Answer 5:

Grid默认情况下应占用的整个宽度ListBox ,因为默认ItemsPanel它是一个VirtualizingStackPanel 。 我假设你没有改变ListBox.ItemsPanel

或许,如果你摆脱了中间的ColumnDefinition (其他是默认的"*" ),并把HorizontalAlignment="Left"你的WrapPanelHorizontalAlignment="Right"ListBox的电话号码。 您可能需要改变该ListBox了一下,以更充分右对齐的电话号码,如创建DataTemplate他们。



Answer 6:

如果你想使用一个Grid ,那么你需要改变你的ColumnDefinition s到是:

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

如果您不需要使用Grid ,那么你可以使用一个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>

注意TextBlock结尾。 没有任何控制"DockPanel.Dock"定义将填补剩余的空间。



Answer 7:

Taeke的回答运作良好,并为每vancutterromney的回答,您可以禁用水平滚动条来摆脱恼人的大小不匹配。 但是,如果你想两全其美的 - 删除滚动条不需要的时候,但是当列表框变得太小了,它会自动启用,你可以使用下面的转换器:

/// <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();
    }
}

根据所需的最大/最小值在XAML然后定义它,以及一个偏移量来处理如在其他的答案提到,恼人的2像素大小不匹配:

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

然后使用在宽度结合的转换器:

<Grid.Width>
    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{StaticResource conDoubleLimiter}"  />
</Grid.Width>


Answer 8:

在Taeke的回答方法迫使水平滚动条。 这可以通过添加一个变换器通过垂直滚动条控件的宽度,以减少网格的宽度是固定的。

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());
        }
    }
}

命名空间添加到您的XAML的根节点。

xmlns:converters="clr-namespace:Converters"

而更新网格宽度使用转换器。

<Grid.Width>
    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{converters:ListBoxItemWidthConverter}"/>
</Grid.Width>


文章来源: How do I make a WPF data template fill the entire width of the listbox?