使Scrollviewer填充DockPanel

时间:2016-07-28 10:52:02

标签: c# wpf

我有点像WPF菜鸟,并且使用DockPanel在ScrollViewer的TextBox中显示电子邮件的文本内容。该面板有一个按钮栏和顶部的电子邮件标题区域,底部的按钮栏,右侧的面板和电子邮件本身应动态填充剩余空间:

[顶部的横幅,下面是一个按钮栏和带有电子邮件标题的框。底部是另一个全宽按钮栏。它们之间的空间分为右侧的固定宽度面板和电子邮件内容的大文本框。 http://rowlandsoftware.com/Screenshots/LongEmail.png

(DockPanel位于网格内部,提供最顶部的位,当电子邮件不可见时使用。)

问题是,如果电子邮件太短或太窄,文本框将无法填充剩余的宽度。在此屏幕截图中,您可以看到框和面板之间的一些基础内容:

[文本框和面板之间是未填充的列。可以看出其中的部分内容。] http://rowlandsoftware.com/Screenshots/TooNarrow.png

XAML是:

<DockPanel x:Name="EmailCanvas" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Visibility="Collapsed" Height="Auto">
    <DockPanel x:Name="topButtonBar" DockPanel.Dock="Top" Height="50" Background="White">
        <Button x:Name="btnReturn" DockPanel.Dock="Left" Content="Return to List" Click="btnReturn_Click" />
        <Image Width="15" Source="Images/transparent.png" />
        <Button x:Name="btnTextToggle" Content="Plain text" Click="btnTextToggle_Click" />
        <Button x:Name="btnZoomOut" Content="Zoom Out" />
        <Button x:Name="btnZoomIn" Content="Zoom In" />
        <Image Width="150" DockPanel.Dock="Right" Source="Images/transparent.png" />
        <Button x:Name="btnPrint" DockPanel.Dock="Right" Content="Print" Width="100"/>
        <Image DockPanel.Dock="Right" Source="Images/transparent.png" />
    </DockPanel>
    <StackPanel x:Name="EmailHeaders" Orientation="Horizontal" DockPanel.Dock="Top" Width="Auto" Background="Linen">
        <StackPanel Orientation="Vertical">
            <TextBlock Text="Subject:" FontSize="16" />
            <TextBlock Text="Time Sent:" FontSize="16"/>
            <TextBlock Text="Other Recipients: " FontSize="16"/>
        </StackPanel>
        <StackPanel Orientation="Vertical">
            <TextBlock x:Name="labSubject" Text="Subject:" FontSize="16" />
            <TextBlock x:Name="labDateTime" Text="Sent:" FontSize="16"/>
            <TextBlock x:Name="labSpare" Text="Other Recipients:" FontSize="14"/>
        </StackPanel>
    </StackPanel>
    <DockPanel x:Name="bottomButtonBar" DockPanel.Dock="Bottom" Height="80" >
        <Image Width="150" DockPanel.Dock="Left" Source="Images/transparent.png" />
        <Button x:Name="btnDelete" DockPanel.Dock="Left" Content="Delete" />
        <Image Width="150" Source="Images/transparent.png" />
        <Button x:Name="btnSave" Content="Save" />
        <Image Width="150" Source="Images/transparent.png" />
        <Button x:Name="btnReply" Content="Reply" />
        <Image Width="150" DockPanel.Dock="Right" Source="Images/transparent.png" />
    </DockPanel>
    <StackPanel DockPanel.Dock="Right" Orientation="Vertical" Background="White" Width="150">
        <Button x:Name="btnAttachments" Content="Attachment"/>
    </StackPanel>
    <ScrollViewer x:Name="eTextViewer" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
        <TextBox x:Name="eText" Background="White" HorizontalAlignment="Stretch" TextWrapping="Wrap" FontFamily="Verdana" FontSize="18" IsReadOnly="True" />
    </ScrollViewer>
    <!--Image Width="Auto" Height="Auto" DockPanel.Dock="Bottom" Source="Images/white.png" /-->
    <WebBrowser x:Name="eHTML" Height="Auto" DockPanel.Dock="Top" Visibility="Collapsed" />
</DockPanel>

该框仅扩展为填充可用高度,而不是宽度。 DockPanel.LastChildFill属性的文档说,

  

如果将LastChildFill属性设置为true(默认设置),则为   无论如何,DockPanel的最后一个子元素总是填充剩余的空间   您在最后一个子元素上设置的任何其他停靠值的值。

msdn.microsoft.com/en-us/library/system.windows.controls.dockpanel.lastchildfill%28v=vs.110%29.aspx

情况似乎并非如此:在我的程序中,它只是填充高度,而不是宽度。 LastFillChild = true是默认值,但明确地将其设置为True False并不会造成一点点差异。

有趣的是,如果你设置DockPanel.Dock =&#34; Top&#34;在ScrollViewer上,它填充可用的宽度而不是高度,在文本框和底部按钮栏之间显示一些底层的东西。同样,这与文档相反,该文档说明在最后一个子元素上设置的停靠值被忽略。

设置Horizo​​ntalAlignment =&#34; Stretch&#34; ScrollViewer和TextBox以及Horizo​​ntalContentAlignment =&#34; Stretch&#34;对ScrollViewer来说并没有太大差别。

所以我的问题是,即使电子邮件的内容太短,我怎样才能确保文本框填充DockPanel中的可用空间?

更新:我刚刚注意到,如果我删除最初设置为Visibility =&#34; Collapsed&#34;的WebBrowser,那么它可以正常工作。我猜它的存在欺骗了DockPanel将其视为LastChild,即使它已经崩溃了。

但是,我需要在显示Web浏览器中的电子邮件和文本框之间切换,因此删除它不是一个选项。当两者都可见时,两者都需要被视为最后一个孩子。有什么想法吗?

更新2:所以我将scrollviewer和Web浏览器包装在另一个容器中,例如网格,这是最后一个孩子。然后我可以在两者之间切换,但它们都填满了空间。

谢谢你们。我不会在没有公开羞辱自己的情况下到达那里;)

1 个答案:

答案 0 :(得分:1)

DockPanel可以使用,但要小心Collapsed项目。虽然文档说折叠的项目对布局没有影响,但是如果它是LastChild,则使用DockPanel。 在我的情况下,解决方案是添加另一个容器作为最后一个子容器,并将我想要在该容器中切换的两个项目放在一起。然后两者都将填充面板中的剩余空间。