如何使WPF数据模板填充列表框的整个宽度?

如何使WPF数据模板填充列表框的整个宽度?,wpf,layout,listbox,datatemplate,Wpf,Layout,Listbox,Datatemplate,我在WPF中有一个ListBoxDataTemplate。我希望一个项目紧挨着列表框的左侧,另一个项目紧挨着右侧,但我不知道怎么做 到目前为止,我有一个网格,有三列,左边和右边有内容,中间是一个占位符,其宽度设置为“*”。我哪里做错了 代码如下: <DataTemplate x:Key="SmallCustomerListItem"> <Grid HorizontalAlignment="Stretch"> <Grid.RowDefiniti

我在WPF中有一个
ListBox
DataTemplate
。我希望一个项目紧挨着
列表框的左侧,另一个项目紧挨着右侧,但我不知道怎么做

到目前为止,我有一个
网格
,有三列,左边和右边有内容,中间是一个占位符,其宽度设置为“*”。我哪里做错了

代码如下:

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

默认情况下,
网格
应占据
列表框
的整个宽度,因为它的默认
项面板
是一个
虚拟化堆栈面板
。我假设您没有更改
ListBox.ItemsPanel


如果您去掉中间的
列定义
(其他列是默认的
“*”
),并将
HorizontalAlignment=“Left”
放在您的
WrapPanel
上,并将
HorizontalAlignment=“Right”
放在
列表框
上查看电话号码,可能会这样。您可能需要稍微更改一下
列表框
,以使电话号码更准确地对齐,例如为他们创建一个
数据模板。

好的,下面是您所拥有的:

第0列:
WrapPanel

第1栏:无任何内容
第2列:
ListBox

<>听起来好像你想在左边缘写<代码> WrabaNele>代码>右边的代码> ListBox < /代码>,空间占用中间剩下的。

最简单的方法是使用
DockPanel
,而不是
网格

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


如果要使用
网格
,则需要将
列定义更改为:

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
<Grid.Width>
    <Binding Path="ActualWidth" 
             RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" />
</Grid.Width>
注意末尾的
TextBlock
。任何未定义“DockPanel.Dock”的控件都将填充剩余空间。

我还必须设置:

HorizontalContentAlignment="Stretch"
在包含
的列表框中


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

扩展Taeke的答案,为
列表框设置
ScrollViewer.HorizontalScrollBarVisibility=“Hidden”
,允许子控件采用父控件的宽度,而不显示滚动条

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

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资源定义中处理。
/// 
[值转换(typeof(double),typeof(double))]
公共密封类双限流转换器:IValueConverter
{
/// 
///最小值,如果设置。如果未设置,则没有最小限制。
/// 
公共双精度?Min{get;set;}
/// 
///最大值,如果设置。如果未设置,则没有最小限制。
/// 
公共双精度?最大值{get;set;}
/// 
///限制完成后应用的偏移值。
/// 
公共双偏移量{get;set;}
公共静态双_defaultFailureValue=0;
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
如果(值==null | |!(值为双精度))
返回_defaultFailureValue;
双D值=(双)值;
双最小值=最小HasValue?最小值:双负不确定性;
双倍最大值=最大HasValue?最大值:双倍正整数;
double retVal=D值限制范围(最小值、最大值)+偏移量;
返回返回;
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
抛出新的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>

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>


你能发布你的XAML,这样就可以清楚地知道你目前拥有什么了吗?Ta pal.在谷歌上寻求帮助,这是第一个链接。很好:)@Eric Haskins Windows Phone的Pivot控件也有同样的问题(
),但是我应该把代码放在哪里?我试了一些,但我想不出来。给Windows Phone用户的一张便条——这行不通;该属性被ListBox的ItemContainerStyle覆盖。为了让它发挥作用,请看Gabriel Mongeon的回答:这一定是最令人讨厌的UI黑客之一。为什么这不是默认设置?Smh。还值得一提的是,如果ListBoxItem有样式,您可能需要将其设置为:
这不会使数据模板填满列表框的宽度。您需要在列表框上使用HorizontalContentAlignment=“Stretch”,如下所述。我喜欢这种方法的简单性。它不仅确保小项目填满宽度,还确保内容希望非常宽的项目被限制为列表框宽度。这正是我搜索的内容