如何使WPF数据模板填充列表框的整个宽度?
我在WPF中有一个如何使WPF数据模板填充列表框的整个宽度?,wpf,layout,listbox,datatemplate,Wpf,Layout,Listbox,Datatemplate,我在WPF中有一个ListBoxDataTemplate。我希望一个项目紧挨着列表框的左侧,另一个项目紧挨着右侧,但我不知道怎么做 到目前为止,我有一个网格,有三列,左边和右边有内容,中间是一个占位符,其宽度设置为“*”。我哪里做错了 代码如下: <DataTemplate x:Key="SmallCustomerListItem"> <Grid HorizontalAlignment="Stretch"> <Grid.RowDefiniti
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”,如下所述。我喜欢这种方法的简单性。它不仅确保小项目填满宽度,还确保内容希望非常宽的项目被限制为列表框宽度。这正是我搜索的内容