长文本的ListBox.ItemTemplate与ListBox宽度不匹配

时间:2018-12-02 10:57:19

标签: c# wpf xaml user-controls

我试图将StackPanel放在ListBox内,并将其放在Grid的一部分UserControl内。

到目前为止,我已经提出了以下XAML,但是我无法确定宽度。当您查看屏幕截图时,您会发现StackPanel的像素太宽了。我在每个元素上都尝试过HorizontalAlignment=Stretch,但是在Width={Binding...}上却设法限制了宽度,尽管并不完美。我想念什么?

<UserControl x:Class="Reusable.Apps.ExceptionControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Reusable.Apps"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800" Width="{Binding (Window.Width), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
    <UserControl.Resources>
        <local:ExceptionVisualizerData x:Key="DesignViewModel" />
        <Style TargetType="TextBlock" x:Key="NameStyle">
            <Setter Property="FontSize" Value="20"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="FontFamily" Value="Consolas"/>
            <Setter Property="Foreground" Value="DarkMagenta"/>
        </Style>
        <Style TargetType="TextBlock" x:Key="MessageStyle">
            <Setter Property="FontSize" Value="16"></Setter>
            <Setter Property="FontFamily" Value="Segoe UI"/>
            <Setter Property="TextWrapping" Value="Wrap"/>
        </Style>
    </UserControl.Resources>
    <Grid Width="{Binding (UserControl.Width), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
        <ListBox ItemsSource="{Binding Exceptions}" d:DataContext="{Binding Source={StaticResource DesignViewModel}}" Width="{Binding (Grid.Width), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel  Width="{Binding (ListBox.Width), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}">
                        <TextBlock Text="{Binding Name}" Style="{StaticResource NameStyle}"  />
                        <TextBlock Text="{Binding Message}" Style="{StaticResource MessageStyle}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

enter image description here

4 个答案:

答案 0 :(得分:1)

参考ListBox的宽度而不是参考ListBoxItem

<StackPanel  Width="{Binding (ListBoxItem.Width), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}">

答案 1 :(得分:1)

听起来您应该摆脱所有宽度绑定,而在StackPanel周围放一个边距,例如:

<StackPanel Margin="10" >

---更新-

沮丧是正确的词。好的,这是解决方案。

(1)用Grid替换StackPanel。

(2)在列表框中,将ScrollViewer.Horizo​​ntalScrollBarVisibility设置为“已禁用”

<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <Grid Margin="10" >
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="Title" Style="{StaticResource NameStyle}"  />
            <TextBlock Grid.Row="1" TextWrapping="Wrap" Text="lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text " Style="{StaticResource MessageStyle}" />
        </Grid>
    </ListBox>

这应该可以解决问题。

答案 2 :(得分:1)

我终于明白了!我找到了similar question,并根据自己的需要采用了answer

<Grid >
    <ListBox ItemsSource="{Binding Exceptions}" d:DataContext="{Binding Source={StaticResource DesignViewModel}}" Margin="30" >
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Width" Value="{Binding (Grid.ActualWidth), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}" />
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Name}" Style="{StaticResource NameStyle}"  />
                    <TextBlock Text="{Binding Message}" Style="{StaticResource MessageStyle}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

诀窍是将Width中的ListBoxItem绑定到父对象。天啊!这很棘手。现在,它在调整窗口大小时也可以很好地缩放。

答案 3 :(得分:1)

重叠的原因是由于ListBoxItem的默认模板,该模板的Padding设置为“ 4,1”,而内部和内部Border对象的BorderThickness设置为“ 1”。您可以使用WPF Snoop之类的工具进行查看。

解决方案是绑定到下一级容器的ActualWidth,在本例中为ContentPresenter。

<ListBox ItemsSource="{Binding DataItems}"
         ScrollViewer.HorizontalScrollBarVisibility="Disabled"
         HorizontalContentAlignment="Stretch">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid Background="Yellow"
                  Width="{Binding RelativeSource={RelativeSource FindAncestor, 
                                                  AncestorType={x:Type ContentPresenter}}, 
                          Path=ActualWidth}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" Text="{Binding Id}" />
                <TextBlock Grid.Row="1" Text="{Binding Description}" TextWrapping="Wrap" />
        </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

请注意在ListBox上设置的属性,以防止内容超出ListBox的宽度,并迫使内容随着ListBox宽度的增加而调整大小。