WPF如何使Viewbox从StackPanel中了解其可用空间

时间:2015-06-29 14:45:36

标签: c# wpf

我有一个基于Soroosh Davaee在http://www.codeproject.com/Tips/773386/WPF-ImageButton的ImageButton示例的自定义WPF控件。自定义控件将Image和TextBlock组合在Button中的水平StackPanel中。 (顺便说一下,要让Soroosh的例子运行,我必须编辑解决方案属性,以便“SampleView”是启动项目,而不是“ExtendedButton”作为启动项目。)

我希望TextBlock中的文本在必要时自动缩小,以避免在文本太长而无法自然适应按钮的情况下在右边缘进行剪裁。例如,如果我编辑Soroosh的MainWindow.xaml以使按钮文本太长而不适合...

    ...
    <EB:ImageButton Width="100" Height="30" Content="TextTooLongToFitInTheButton" Grid.Row="2"
    ...
    <EB:ImageButton Width="100" Height="30" Content="TextTooLongToFitInTheButton" Grid.Row="2"
    ...

...结果是以下带有剪辑文本的按钮:

Buttons with clipped text

在研究这个问题时,似乎自动缩小TextBlock内容的最简单方法是将其包装在Viewbox中:

<Viewbox StretchDirection="DownOnly" Stretch="Fill">
    <TextBlock ... />
</Viewbox>

DownOnly显然阻止了Viewbox 放大文本以填充空间,而Fill(而不是Uniform)似乎告诉它要拉伸(缩小)需要缩小的维度(即我的水平维度)。​​

在Soroosh的示例Generic.xaml文件中,我将TextBlock包装在这样的Viewbox中:

     <Button >
         <StackPanel Orientation="Horizontal">
             <Image Margin="2 0"
                    Source="{TemplateBinding Image}"
                    Width="{TemplateBinding ImageWidth}"
                    Height="{TemplateBinding ImageHeight}"
                    Visibility="{TemplateBinding Image,Converter={StaticResource VisibilityConvertor}}"
                    VerticalAlignment="Center"/>
I added-->   <Viewbox StretchDirection="DownOnly" Stretch="Fill">
             <TextBlock Text="{TemplateBinding Content}"
                    VerticalAlignment="Center"/>
I added-->   </Viewbox>
         </StackPanel>
     </Button>

这产生了完全相同的剪辑按钮文本。刚尝试,我试图强制Viewbox有一个固定的宽度......

             <Viewbox StretchDirection="DownOnly" Stretch="Fill" Width="60">

......产生了这个:

Viewbox with manually-sized width

...显示了Viewbox的功能,只要它能够以某种方式知道它在StackPanel内的可用宽度。

我注意到如果我将Viewbox包装在整个StackPanel周围,它会成功自动缩小StackPanel的整个内容:

     <Button >
         <Viewbox StretchDirection="DownOnly" Stretch="Fill" Width="60">
             <StackPanel Orientation="Horizontal">
                 <Image Margin="2 0"
                    Source="{TemplateBinding Image}"
                    Width="{TemplateBinding ImageWidth}"
                    Height="{TemplateBinding ImageHeight}"
                    Visibility="{TemplateBinding Image,Converter={StaticResource VisibilityConvertor}}"
                    VerticalAlignment="Center"/>
                 <TextBlock Text="{TemplateBinding Content}"
                    VerticalAlignment="Center"/>
             </StackPanel>
         </Viewbox>
     </Button>

......几乎产生了我想要的东西:

Viewbox wrapping the entire StackPanel

...但是图片和文字都缩小了,我希望只收缩文字

如何让Viewbox(仅包装TextBox)从StackPanel的单元格中知道它的可用宽度(和我认为的高度)?

1 个答案:

答案 0 :(得分:2)

这是一个常见问题。解决方案只是使用StackPanel进行任何需要重新调整子控件大小的布局。对于这份工作来说,这不是正确的Panel。相反,请尝试使用Grid面板,调整其子控件的大小。 StackPanel控件实际上只适用于最基本的布局任务...尝试更冒险的事情,你会发现自己遇到了这些问题。

另一种选择是使用TextBlock.TextTrimming Property来修剪文本......您也可以将全文放入ToolTip