调整大小后如何使用 Expander 保持 WPF 窗口的大小适合内容
我有一个带有 SizeToContent="Height"
的 WPF 窗口。 此窗口包含一个
,显示最近活动的列表。 我想要的是,当扩展器扩展时,窗口的大小会按比例增长。 隐藏后,窗口再次按比例调整大小。 如果调整窗口大小,则扩展器及其包含的列表视图应该增大以使用新空间。 (不要介意那里的颜色可以帮助我弄清楚这一点):
普通视图
替代文本 http://www.deploylx.com/so/wpfexpander/Open.png
折叠
替代文本 http://www.deploylx.com/so/wpfexpander/Closed.png
调整为新空间
替代文本 http://www.deploylx.com/so/wpfexpander/Expanded .png
到目前为止,效果很好。 当调整窗口大小后
折叠时就会出现问题。 窗口不会再次折叠,而是简单地隐藏列表视图:
调整大小后折叠
我的直觉告诉我,当窗口调整大小并因此覆盖 SizeToContent
属性。 那么,如何让窗口在调整大小后保持其大小适合内容行为呢?
当前 XAML:
<Window x:Class="DeployLX.Licensing.Nlm.Admin.v3.DashboardWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Dashboard" Width="504" SizeToContent="Height" Height="275">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="E_xit" Command="{Binding Path=CloseCmd}" />
</MenuItem>
</Menu>
<Grid DockPanel.Dock="Top" Margin="8" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.RowSpan="2" Grid.Row="0" Grid.Column="0" Margin="0,0,8,0">
<Rectangle Fill="Red" />
<TextBlock>ActiveCount</TextBlock>
</Grid>
<Grid Grid.Row="0" Grid.Column="1" Margin="0,0,0,4">
<Rectangle Fill="Green" />
<TextBlock>Authorization</TextBlock>
</Grid>
<Grid Grid.Row="1" Grid.Column="1" Margin="0,4,0,0">
<Rectangle Fill="Blue" />
<TextBlock>Authorization</TextBlock>
</Grid>
</Grid>
<Expander Header="Recent Activity" Margin="8" IsExpanded="True">
<ListView IsSynchronizedWithCurrentItem="True" MinHeight="100">
<ListView.View>
<GridView>
<GridViewColumn Header="Status"/>
</GridView>
</ListView.View>
</ListView>
</Expander>
</DockPanel>
</Window>
更新: 我已尝试侦听扩展器的 Collapsed 事件并重置 Windows SizeToContent
属性。 这几乎有效。 它会导致窗口再次折叠,但是当再次展开时,它会恢复到原来的 100 像素高度。 虽然存储和捕获这些信息是可行的,但它有点老套并且容易出错。
I've got a WPF window with SizeToContent="Height"
. This window contains an <Expander />
that displays a list of recent activity. What I'd like is when the expander is expanded the window grows in size proportionally. When hidden the window again resizes proportionally. If the window is resized the expander and it's contained list view should grow to use the new space. (don't mind the colors there there to help me figure this out):
Normal View
alt text http://www.deploylx.com/so/wpfexpander/Open.png
Collapsed
alt text http://www.deploylx.com/so/wpfexpander/Closed.png
Resized to new space
alt text http://www.deploylx.com/so/wpfexpander/Expanded.png
So far this works great. The problem comes when the <Expander />
is collapsed after the window is resized. Rather than the window collapsing again, the list view is simply hidden:
Collapsed after Resize
alt text http://www.deploylx.com/so/wpfexpander/Collapsed.png
My intuition tells me that the Height
of the window is being set when the window resizes and thus overrides the SizeToContent
property. So, how can I get the window to keep it's size to content behavior after it's been resized?
Current XAML:
<Window x:Class="DeployLX.Licensing.Nlm.Admin.v3.DashboardWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Dashboard" Width="504" SizeToContent="Height" Height="275">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="E_xit" Command="{Binding Path=CloseCmd}" />
</MenuItem>
</Menu>
<Grid DockPanel.Dock="Top" Margin="8" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.RowSpan="2" Grid.Row="0" Grid.Column="0" Margin="0,0,8,0">
<Rectangle Fill="Red" />
<TextBlock>ActiveCount</TextBlock>
</Grid>
<Grid Grid.Row="0" Grid.Column="1" Margin="0,0,0,4">
<Rectangle Fill="Green" />
<TextBlock>Authorization</TextBlock>
</Grid>
<Grid Grid.Row="1" Grid.Column="1" Margin="0,4,0,0">
<Rectangle Fill="Blue" />
<TextBlock>Authorization</TextBlock>
</Grid>
</Grid>
<Expander Header="Recent Activity" Margin="8" IsExpanded="True">
<ListView IsSynchronizedWithCurrentItem="True" MinHeight="100">
<ListView.View>
<GridView>
<GridViewColumn Header="Status"/>
</GridView>
</ListView.View>
</ListView>
</Expander>
</DockPanel>
</Window>
UPDATE: I've tried listening to the Collapsed event of the expander and resetting the Windows SizeToContent
property. This almost works. It will cause it to collapse the window again but when expanded again it goes back to the original 100 pixel height. While it's feasible to store and capture this info it smells hacky and prone to errors.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果要使用 SizeToContent,则必须使窗口不可调整大小。 另外,您不应该使用 SizeToContent="Height",然后设置显式高度。 想一想 - WPF 应该相信窗口高度、用户设置还是内容中的哪一个? 它不能只是在两者之间来回切换。
You have to make your window non-resizeable if you're going to use SizeToContent. Also, you shouldn't use SizeToContent="Height", and then set an explicit Height. Think about it - which one should WPF believe for the window height, the user's setting or the Content? It can't just switch back and forth between the two.
最简单的解决方法是通过在窗口上设置
ResizeMode="NoResize"
来避免手动调整大小。 但是,如果您有WindowStyle="None"
,我注意到在 Vista Aero 上,这会导致窗口完全脱落“镀铬”,并且窗口看起来很尴尬。 另外,这有点逃避,因为看起来您想为用户提供调整大小的功能。问题是您有两个相互冲突的目标:1.)折叠扩展器控件时您总是想要
SizeToContent="Height"
,2.)您想要SizeToContent="Height"
> 展开扩展器控件时除非用户手动调整了窗口大小 (SizeToContent="Manual"),在这种情况下您希望返回到用户的手动高度。哎呀。 我认为您无法自行保存扩展的高度。 一旦您在折叠事件处理程序中恢复到
SizeToContent="Height"
,WPF 将不会记住用户在展开时的手动高度。The easiest way to cope is to take manual resizing out of the equation by setting
ResizeMode="NoResize"
on the window. However, if you haveWindowStyle="None"
I've noticed that on Vista Aero this causes the window to completely shed the "chrome" and the window looks awkward. Also, this somewhat of a cop out since it looks like you want to give the user resizing capabilities.The problem is that you have two conflicting goals: 1.) you always want
SizeToContent="Height"
when collapsing the expander control, 2.) you wantSizeToContent="Height"
when expanding the expander control unless the user has manually resized the window (SizeToContent="Manual"), in which case you'd like to return to the user's manual height.Yikes. I don't think you can get around saving the expanded height yourself. WPF won't remember the user's manual height upon expanding once you've reverted back to
SizeToContent="Height"
in your collapsed event handler.试试这个,它应该适合您的需求:
Try this, it should fit your needs:
我发现将窗口的主体放在视图中,然后将视图作为窗口中的唯一子视图解决了类似的问题......
不是最理想的解决方案,但它似乎有效。
I've found that putting the body of my Window in a View and then putting the view as the sole child in the window solved similar problems...
Not the most desirable solution, but it seems to work.
正如我在我的问题中发现的,将高度设置为 Double.NaN 会导致它重置为 SizeToContent 幸福。 我不知道它是否会记住你的扩展器的尺寸。 您可以尝试使用 Kent 的 Resizer 控件将大小调整行为移至扩展器而不是包含窗口。
As I discovered in my question, setting the Height to Double.NaN causes it to reset to SizeToContent happiness. I don't know if it will remember the size of your expander though. You might try Kent's Resizer control to move the sizing behavior to the expander rather than the containing window.