【问题标题】:Prevent controls from forcing parents to resize防止控件强迫父母调整大小
【发布时间】:2014-04-14 03:48:56
【问题描述】:

我要疯了,想弄清楚这一点。我有一个 DockPanel,其中一些东西停靠在 Top 上,还有一个 ItemsControl 作为它的中心内容(它表现为一个包含更多 DockPanel 的 WrapPanel)。

我希望中心 ItemsControl 根据需要扩展父 DockPanel 的宽度。我不希望停靠在 DockPanel 顶部的东西导致 DockPanel 展开,但我希望它使用 ItemsControl 的宽度所请求的任何空间。

这里有一些大大简化的 XAML,仍然可以捕获行为:

<Window x:Class="SizingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="Width" Height="150">
    <Grid>
        <DockPanel>
            <TextBlock DockPanel.Dock="Top">Here's some really long text that should not force the window to expand. Just clip if it's wider than the buttons.</TextBlock>
            <WrapPanel Orientation="Vertical">
                <Button>Button 1</Button>
                <Button>Button 2</Button>
                <Button>Button 3</Button>
                <Button>Button 4</Button>
                <Button>Button 5</Button>
                <Button>Button 6</Button>
                <Button>Button 7</Button>
                <Button>Button 8</Button>
                <Button>Button 9</Button>
                <Button>Button 10</Button>
            </WrapPanel>
        </DockPanel>
    </Grid>
</Window>

换句话说,WrapPanel/DockPanel/Grid/Window 应该调整它们的宽度以适应 WrapPanel 的按钮列,但我希望在用完 WrapPanel 请求的所有可用空间后简单地裁剪 TextBlock。调整窗口高度(这会导致 WrapPanel 自行调整并添加/删除列)应该会导致 TextBlock 更改宽度 - 和剪辑 - 以匹配 WrapPanel。我该怎么做?

【问题讨论】:

    标签: wpf xaml wpf-4.5


    【解决方案1】:

    您只需要进行一些更改。首先,您需要将WrapPanel延伸到完整的Width。然后您可以将TextBlock.Width 属性数据绑定到WrapPanel.ActualWidth 属性。最后,您还需要将TextBlock 上的HorizontalAlignment 属性设置为Left。这应该可以解决问题:

    <Grid>
        <DockPanel>
            <TextBlock DockPanel.Dock="Top" HorizontalAlignment="Left" 
                Width="{Binding ActualWidth, ElementName=Panel}" Text="Here's some really 
                long text that should not force the window to expand..." />
            <WrapPanel Name="Panel" Orientation="Vertical" HorizontalAlignment="Left">
                <Button>Button 1</Button>
                <Button>Button 2</Button>
                <Button>Button 3</Button>
                <Button>Button 4</Button>
                <Button>Button 5</Button>
                <Button>Button 6</Button>
                <Button>Button 7</Button>
                <Button>Button 8</Button>
                <Button>Button 9</Button>
                <Button>Button 10</Button>
            </WrapPanel>
        </DockPanel>
    </Grid>
    

    最后要注意的是,如果您使用TextTrimming 属性在文本被截断之前的末尾添加省略号 (...),效果会更好。你可以这样做:

    <TextBlock DockPanel.Dock="Top" HorizontalAlignment="Left" Width="{Binding ActualWidth,
        ElementName=Panel}" Text="Here's some really long text that should not force the 
        window to expand..." TextTrimming="CharacterEllipsis" />
    

    【讨论】:

    • 谢谢,我认为 Width 绑定和 Horizo​​ntalAlignment 的组合是我所缺少的。到目前为止,它与父 ItemsControl (ScrollViewer) 和精心设计的子控件集配合得很好。我之前遇到了一些奇怪的包装和尺寸问题,但到目前为止一切都很好......
    【解决方案2】:

    你可以看看这个,也许你会在那里找到解决问题的方法:

    <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="150"
            xmlns:local="clr-namespace:WpfApplication1">
        <Grid>
            <DockPanel LastChildFill="False">
                <TextBlock DockPanel.Dock="Top">
                    Here's some really long text that should not force the window to expand. Just clip if it's wider than the buttons.
                </TextBlock>
                <WrapPanel x:Name="wrapPanel" DockPanel.Dock="Left" Orientation="Vertical">
                    <Button>Button 1</Button>
                    <Button>Button 2</Button>
                    <Button>Button 3</Button>
                    <Button>Button 4</Button>
                    <Button>Button 5</Button>
                    <Button>Button 6</Button>
                    <Button>Button 7</Button>
                    <Button>Button 8</Button>
                    <Button>Button 9</Button>
                    <Button>Button 10</Button>
                </WrapPanel>
            </DockPanel>
        </Grid>
    </Window>
    

    告诉 DockPanel 不要用最后一个孩子填充其可用空间,以防止 WrapPanel 拉伸。最后告诉窗口采用 WrapPanel 的计算宽度,如下所示:

    public MainWindow()
    {
        InitializeComponent();
        this.wrapPanel.Loaded += wrapPanel_Loaded;
    }
    
    void wrapPanel_Loaded(object sender, RoutedEventArgs e)
    {
        this.Width = this.wrapPanel.ActualWidth + 20;
    }
    

    就是这样。文本将被剪掉,但当您调整窗口大小时,文本将计算新的剪裁。

    【讨论】:

      猜你喜欢
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      相关资源
      最近更新 更多