<Border CornerRadius="2,2,2,2" BorderThickness="1" BorderBrush="LightSkyBlue" Margin="5,2,2,2" x:Name="PersonBorder" Visibility="Collapsed">
<StackPanel Orientation="Vertical">
<ListBox Name="personListBoxTest"
BorderThickness="0"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Auto"
HorizontalContentAlignment="Stretch"
Background="LemonChiffon"
>
<ListBox.ItemTemplate >
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal" Background="Pink">
<StackPanel Orientation="Horizontal" Visibility="{Binding ElementName=Involvement, Path=Text, Converter={StaticResource cIsVisibleOrCollapsed}}" Margin="0,0,5,0">
<TextBlock Text="Involvement:"/>
<TextBlock Margin="5,0,0,0" Text="{Binding Path=NameInvolvementType}" Foreground="Blue" x:Name="Involvement"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name:"/>
<TextBlock Margin="3,0,0,0" Text="{Binding Path=FirstName}" Foreground="Blue" />
<TextBlock Margin="3,0,0,0" Text="{Binding Path=MiddleName}" Foreground="Blue" />
<TextBlock Margin="3,0,0,0" Text="{Binding Path=LastName}" Foreground="Blue" />
<TextBlock Margin="3,0,0,0" Text="{Binding Path=NameSuffix}" Foreground="Blue" />
<TextBlock Margin="5,0,0,0" Text="DOB:"/>
<TextBlock Margin="3,0,0,0" Text="{Binding Path=BirthDate, StringFormat=MM/dd/yyyy}" Foreground="Blue" />
</StackPanel>
</StackPanel>
<StackPanel Visibility="{Binding ElementName=myEventAddress,Path=Visibility, Converter={StaticResource cVisibilityMirror}}" Orientation="Horizontal" >
<TextBlock Text="Address:" />
<EventDet:EventAddress Margin="5,0,0,0" x:Name="myEventAddress" Foreground="Blue" CityTextBlockOrientation="Horizontal" />
</StackPanel>
<StackPanel Visibility="{Binding ElementName=Phone1, Path=Text, Converter={StaticResource cIsVisibleOrCollapsed}}" Orientation="Horizontal">
<TextBlock Text="Home:" />
<TextBlock Margin="5,0,0,0" Text="{Binding Path=Phone1}" Foreground="Blue" x:Name="Phone1"/>
</StackPanel>
<StackPanel Visibility="{Binding ElementName=Phone2, Path=Text, Converter={StaticResource cIsVisibleOrCollapsed}}" Orientation="Horizontal">
<TextBlock Text="Mobile:" />
<TextBlock Margin="5,0,0,0" Text="{Binding Path=Phone2}" Foreground="Blue" x:Name="Phone2"/>
</StackPanel>
<StackPanel Visibility="{Binding ElementName=Phone3, Path=Text, Converter={StaticResource cIsVisibleOrCollapsed}}" Orientation="Horizontal">
<TextBlock Text="Work:" />
<TextBlock Margin="5,0,0,0" Text="{Binding Path=Phone3}" Foreground="Blue" x:Name="Phone3"/>
</StackPanel>
<StackPanel x:Name="PersonAlertSP" Visibility="Collapsed" Background="WhiteSmoke">
<TextBlock Text="Alerts:" />
<ListBox ItemsSource="{Binding Path=PersonAlertList}" x:Name="PersonAlertListBox" BorderThickness="1" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=AlertType}" Margin="0,0,5,0" Foreground="Blue" Width="150"/>
<TextBlock Text="{Binding Path=Description}" Margin="0,0,5,0" Foreground="Blue"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Border>
代码背后的代码:
//this is a little unweidly, but its test code until this works
MobileWPF.singleton.EventDetailsTabControl.myEventDetailControl.personListBoxTest.ItemsSource =
dc.SessionEvent.SessionPersons.ToList();
这是一个包含6个项目的结果图像,所有数据都是无意义的测试数据:
编辑2:
稍微玩了一下后,我想这就是发生的事情......首先,ListBox贪婪并占用最大量的垂直空间,然后完成一些IValueConverter计算,并且一些元素被折叠。但是,完成此操作后,ListBox高度不会更新。
编辑3:
我尝试将PersonListBoxTest转换为ItemsControl,而不是ListBox,只有代码和<ItemsControl.ItemTemplate >
声明的差异......现在它按预期工作,没有额外的空格。
因此,ItemsControl以某种方式尊重我的一些元素通过IValueConverters折叠的事实,而ListBox则没有。我在使用ListBox中的VirtualizingStackPanel属性,在测试ItemsControl之前将IsVirtualizing设置为true和false(无更改)。
我会向任何能够解释为什么它如何发挥作用的人提出要点 感谢大家的回答,你永远不知道会有什么不同。
以下是正在使用的IValueConverter示例,它们大致相同。
[ValueConversion(typeof(object), typeof(System.Windows.Visibility))]
public class NullToVisibleOrCollapsed : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return System.Windows.Visibility.Collapsed;
if (value is Image)
{
if (((Image)value).Source == null) return System.Windows.Visibility.Collapsed;
return System.Windows.Visibility.Visible;
}
if (value is string)
{
string myString = (string)value;
if (string.IsNullOrEmpty(myString) == true)
return System.Windows.Visibility.Collapsed;
}
if (value is int)
{
int myInt = (int)value;
if (myInt == 0)
return System.Windows.Visibility.Collapsed;
}
return System.Windows.Visibility.Visible;
}
答案 0 :(得分:2)
发生这种情况的原因是因为ListBox会覆盖默认的ItemsPanelTemplate
设置以使用VirtualizingStackPanel
。这样做是因为VirtualizingStackPanel支持UI虚拟化,这意味着只评估和创建可见控件,这可以提高大型数据集的性能。
在UI虚拟化期间,控件会检查子元素的可见性,然后测量它及其后代。这种评估顺序是您看到额外空间的关键原因。您正在使用子元素的绑定值来设置父元素的可见性。
<StackPanel
...
Visibility="{Binding
ElementName=Phone1,
Path=Text,
Converter={StaticResource cIsVisibleOrCollapsed}}">
<TextBlock
x:Name="Phone1"
Text="{Binding Path=Phone1}" />
</StackPanel>
当框架评估StackPanel时,Visibility尚未设置,因此默认为Visible。如果您将Visibility绑定更改为使用与子属性相同的绑定路径,则可以解决此问题。
<StackPanel
...
Visibility="{Binding Phone1,
Converter={StaticResource cIsVisibleOrCollapsed}}">
<TextBlock
x:Name="Phone1"
Text="{Binding Path=Phone1}" />
</StackPanel>
您还可以指定FallbackValue
Collapsed
,它告诉引擎在无法解析绑定的情况下使用Visibility.Collapsed。但是,我会谨慎地这样做,因为这似乎会搞砸UI测量,这可能会产生其他不良影响。
最后,普通的ItemsControl模板不需要预先测量,因为它不支持UI虚拟化。换句话说,生成控件然后隐藏,并相应地调整大小。
答案 1 :(得分:1)
默认情况下,控件将展开以填充其容器将为其提供的所有空间。这就是你所看到的,并且它是预期的,因为你没有告诉它做任何其他事情(即你没有在ListBox上设置任何对齐属性)。
如果您希望ListBox仅占用显示其项目所需的高度,则将其VerticalAlignment
属性设置为默认值Stretch
以外的其他属性。例如:
<ListBox Name="personListBoxTest"
VerticalAlignment="Top"
...
如果您愿意,也可以使用Bottom
或Center
- 对您的布局最有意义。
假设您使用Top
,那么如果列表框只有足够的项目来填充ListBox的父级给出的空间的一半,那么整个ListBox将占用那么多空间,而父级的其余部分将是空的。但是如果有这么多ListBox项目(或者父项变得如此之小)以至于项目都不适合,ListBox将填充所有空间并显示滚动条,就像你想要它一样。
答案 2 :(得分:0)
将ListBox
换成Grid
并将其设置为VerticalAlignment="Top"
听起来你的ListBox
控件位于另一个元素中,例如Grid
或DockPanel
,默认情况下会延伸它的子节点以填充所有可用空间。
<Grid>
<ListBox VerticalAlignment="Top" ... />
</Grid>
答案 3 :(得分:0)
如果我正确理解您的问题,您可以使用Height="Auto"
作为列表框(或其他控件),如果您想根据列表框更新窗口高度,可以将窗口高度绑定到列表框使用以下代码:
Height="{Binding ActualHeight, ElementName=personListBoxTest}"
我希望它对你有用。
答案 4 :(得分:0)
...也许
<StackPanel LastChildFill="False">
答案 5 :(得分:0)
您需要使包含ListBox的容器的高度为AUTO
ListBox1位于一行高度AUTO
ListBox2的行高为*
这将允许你在列表框中具有正确的高度作为容器中值的大小,直到容纳它的容器的最大高度......有点令人困惑,但希望它有意义。< / p>
希望有所帮助!
请参阅此示例代码
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox Grid.Column="0" Grid.Row="0" Background="blue">
<ListBoxItem>I'm an item in listbox1</ListBoxItem>
<ListBoxItem>I'm an item in listbox1</ListBoxItem>
<ListBoxItem>I'm an item in listbox1</ListBoxItem>
<ListBoxItem>I'm an item in listbox1</ListBoxItem>
<ListBoxItem>I'm an item in listbox1</ListBoxItem>
<ListBoxItem>I'm an item in listbox1</ListBoxItem>
</ListBox>
<ListBox Grid.Column="1" Grid.RowSpan="2" Grid.Row="0" Background="red">
<ListBoxItem>I'm an item in listbox2</ListBoxItem>
<ListBoxItem>I'm an item in listbox2</ListBoxItem>
<ListBoxItem>I'm an item in listbox2</ListBoxItem>
<ListBoxItem>I'm an item in listbox2</ListBoxItem>
<ListBoxItem>I'm an item in listbox2</ListBoxItem>
<ListBoxItem>I'm an item in listbox2</ListBoxItem>
<ListBoxItem>I'm an item in listbox2</ListBoxItem>
</ListBox>
</Grid>