我有点像WPF noob,正在使用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并没有什么区别。
有趣的是,如果你在ScrollViewer上设置DockPanel.Dock="Top",它会填充可用的宽度而不是高度,从而在文本框和底部按钮栏之间显示一些底层内容。同样,这与文档中所说的忽略最后一个子元素上设置的dock值相反。
将HorizontalAlignment="Stretch"设置为ScrollViewer和TextBox,将HorizontalContentAlignment="Stretche"设置为ScrollViewer并没有什么区别。
所以我的问题是,即使电子邮件的内容太短,我如何确保文本框填充DockPanel中的可用空间?
更新:我刚刚注意到,如果我删除最初设置为Visibility="Collapsed"的WebBrowser,那么它可以正常工作。我猜它的存在欺骗了DockPanel,使其将其视为LastChild,即使它已经崩溃。
然而,我需要在网络浏览器中显示电子邮件和文本框之间切换,所以删除它不是一个选项。当它们都可见时,需要将它们视为最后一个孩子。有什么想法吗?
更新2:所以我将滚动查看器和web浏览器包装在另一个容器中,例如网格,它是Last Child。然后我可以在两者之间切换,但它们都填满了空间。
谢谢大家。如果不在公共场合羞辱自己,我是不可能到达那里的;)
DockPanel可以工作,但要注意折叠的项目。尽管文档中说折叠的项目对布局没有影响,但对于DockPanel,如果它是LastChild,则会影响布局。在我的案例中,解决方案是添加另一个容器作为最后一个子容器,并将我想要在其中切换的两个项目放置在该容器中。然后两者都将填充面板中的剩余空间。