如何使WPF窗口的大小与调整后的扩展器保持一致

时间:2022-06-04 02:25:23

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):

我有一个WPF窗口,它的SizeToContent="Height"。此窗口包含一个 ,显示最近的活动列表。我想要的是当扩展器展开时窗口按比例增大。当隐藏窗口时,再次按比例调整大小。如果窗口被调整了大小,则包含列表视图的扩展将使用新的空间。(别介意那里的颜色帮我弄清楚):

Normal View

普通视图

alt text http://www.deploylx.com/so/wpfexpander/Open.png

alt文本http://www.deploylx.com/so/wpfexpander/Open.png

Collapsed

倒塌

alt text http://www.deploylx.com/so/wpfexpander/Closed.png

alt文本http://www.deploylx.com/so/wpfexpander/Closed.png

Resized to new space

调整大小以新空间

alt text http://www.deploylx.com/so/wpfexpander/Expanded.png

alt文本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

alt文本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?

我的直觉告诉我,窗口的高度是在窗口调整大小时设置的,从而覆盖SizeToContent属性。那么,如何让窗口在调整大小后保持其大小为内容行为?

Current XAML:

目前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.

更新:我尝试了侦听扩展器的折叠事件并重新设置Windows SizeToContent属性。这几乎工作。它会再次折叠窗口但是当再次扩展时它会回到原来的100像素高度。虽然存储和捕获这些信息是可行的,但它闻起来很陈腐,容易出错。

5 个解决方案

#1


58  

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.

如果你要使用SizeToContent,你必须使你的窗口不可调整。另外,您不应该使用SizeToContent="Height",然后设置显式的高度。想一想——对于窗口高度、用户的设置或内容,WPF应该相信哪一个?它不能在两者之间来回切换。

#2


10  

The easiest way to cope is to take manual resizing out of the equation by setting ResizeMode="NoResize" on the window. However, if you have WindowStyle="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.

最简单的方法是通过在窗口上设置ResizeMode="NoResize",将手动调整大小从等式中去掉。但是,如果你有WindowStyle="None",我注意到在Vista Aero上,这会导致窗口完全去掉"chrome",窗口看起来很尴尬。此外,这有点像是在逃避现实,因为看起来您希望为用户提供调整大小的功能。

The problem is that you have two conflicting goals: 1.) you always want SizeToContent="Height" when collapsing the expander control, 2.) you want SizeToContent="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.

问题是您有两个冲突的目标:1.)在折叠扩展器控件时总是希望SizeToContent=“Height”,2.)在扩展扩展器控件时希望SizeToContent=“Height”,除非用户手动调整窗口的大小(SizeToContent=“Manual”),在这种情况下您希望返回用户的手动高度。

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.

呵。我认为你不可能自己去拯救膨胀的高度。当您在折叠事件处理程序中恢复到SizeToContent=“height”时,WPF不会记得用户的手动高度。

#3


2  

Try this, this should fit your needs: SizeToContent="WidthAndHeight" Height="Auto" Width="Auto"

试试这个,它应该适合您的需要:SizeToContent="WidthAndHeight" Height="Auto" Width="Auto"

#4


1  

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.

正如我在我的问题中发现的,将高度设置为双倍。NaN使它重置为幸福的大小。我不知道它是否记得你的扩展器的大小。您可以尝试Kent的Resizer控件,将大小行为移动到扩展器而不是包含窗口。

#5


1  

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.

这并不是最理想的解决方案,但似乎行得通。

#1


58  

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.

如果你要使用SizeToContent,你必须使你的窗口不可调整。另外,您不应该使用SizeToContent="Height",然后设置显式的高度。想一想——对于窗口高度、用户的设置或内容,WPF应该相信哪一个?它不能在两者之间来回切换。

#2


10  

The easiest way to cope is to take manual resizing out of the equation by setting ResizeMode="NoResize" on the window. However, if you have WindowStyle="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.

最简单的方法是通过在窗口上设置ResizeMode="NoResize",将手动调整大小从等式中去掉。但是,如果你有WindowStyle="None",我注意到在Vista Aero上,这会导致窗口完全去掉"chrome",窗口看起来很尴尬。此外,这有点像是在逃避现实,因为看起来您希望为用户提供调整大小的功能。

The problem is that you have two conflicting goals: 1.) you always want SizeToContent="Height" when collapsing the expander control, 2.) you want SizeToContent="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.

问题是您有两个冲突的目标:1.)在折叠扩展器控件时总是希望SizeToContent=“Height”,2.)在扩展扩展器控件时希望SizeToContent=“Height”,除非用户手动调整窗口的大小(SizeToContent=“Manual”),在这种情况下您希望返回用户的手动高度。

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.

呵。我认为你不可能自己去拯救膨胀的高度。当您在折叠事件处理程序中恢复到SizeToContent=“height”时,WPF不会记得用户的手动高度。

#3


2  

Try this, this should fit your needs: SizeToContent="WidthAndHeight" Height="Auto" Width="Auto"

试试这个,它应该适合您的需要:SizeToContent="WidthAndHeight" Height="Auto" Width="Auto"

#4


1  

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.

正如我在我的问题中发现的,将高度设置为双倍。NaN使它重置为幸福的大小。我不知道它是否记得你的扩展器的大小。您可以尝试Kent的Resizer控件,将大小行为移动到扩展器而不是包含窗口。

#5


1  

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.

这并不是最理想的解决方案,但似乎行得通。