WPF将控制保持在完美的矩形形状(装订宽度和高度)

时间:2011-01-24 16:12:47

标签: wpf binding shape

目前,我正在努力让控件在WPF中以盒子形状显示,而不需要对代码产生结果。以下是我希望它看起来像的一个工作示例:

  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="120"/>
      <RowDefinition Height="3" />
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal">
      <Button Margin="6" VerticalAlignment="Stretch" Width="{Binding Path=ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}">
        <Grid>
          <Grid.RowDefinitions>
           <RowDefinition Height="*" />
           <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
          <Image Source="http://blog.joeclarmusic.com/images/rss-icon.jpg" />
          <TextBlock Foreground="Black" TextAlignment="Center" Grid.Row="1" FontSize="11" Text="{Binding Path=Name}" Margin="0, 5, 0, 0" HorizontalAlignment="Center" TextWrapping="Wrap" />
        </Grid>
      </Button>
    </StackPanel>
    <GridSplitter Grid.Row="1" Background="#DDDDDD" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
  </Grid>

好的,这很酷很好。在我目前的设计中,我使用ItemsControl并显示图像列表。由于这样的列表可以超出窗口的宽度,我想在禁用VerticalScrollBar的StackPanel周围添加ScrollViewer(因为我只希望它从左向右流动,我只需要Horizo​​ntalScrollBar)。

添加ScrollViewer后:

  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="120"/>
      <RowDefinition Height="3" />
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ScrollViewer>
      <StackPanel Orientation="Horizontal">
        <Button Margin="6" VerticalAlignment="Stretch" Width="{Binding Path=ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}">
          <Grid>
          <Grid.RowDefinitions>
           <RowDefinition Height="*" />
           <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
          <Image Source="http://blog.joeclarmusic.com/images/rss-icon.jpg" />
          <TextBlock Foreground="Black" TextAlignment="Center" Grid.Row="1" FontSize="11" Text="{Binding Path=Name}" Margin="0, 5, 0, 0" HorizontalAlignment="Center" TextWrapping="Wrap" />
         </Grid>    
        </Button>
      </StackPanel>
    </ScrollViewer>
    <GridSplitter Grid.Row="1" Background="#DDDDDD" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
  </Grid>

在我的电脑中使用kaxaml 1.7.1运行时的上述图像:jonatan.nilsson.is/wpf_with_scrollviewer.jpg

如果您在Kaxaml(或WPF窗口/页面)中运行button will now keep on getting bigger and bigger (both width and height)。我所做的唯一改变是在StackPanel周围添加ScrollViewer。其他一切都是一样的,那么为什么它在滚动浏览器里面会不断变大?

我在这里做错了什么?

编辑: 添加了第二个示例中结果的图像。

2 个答案:

答案 0 :(得分:1)

好的,我找到了解决方案。如果满足以下条件,则会发生此“行为”:

  • 按钮的内容包含图像
  • 宽度/高度已绑定到它的高度/宽度。
  • 按钮内容高于宽度(当绑定设置为高度 - >宽度时)

您可以非常轻松地测试它。如果删除除了图像之外的Button.Content中的所有内容,整个事情“几乎”可以工作(如果你使用GridSplitter使行高变小,按钮不会变小,但它会变得更大)。

但是,如果您随后向图像添加Margin="0, 0, 0, 1",则会发生与之前相同的行为(即,它会无限增长)。

发生的事情基本上是这样的:

  1. 按钮高度高于宽度。
  2. 绑定看到并使其更宽
  3. 图像看到它变得更宽并且为了保持它的比例而使自己更高(在这种情况下为1:1)
  4. Image推高了自己。
  5. 按钮高度高于宽度,请转到步骤2.
  6. 基本上,因为图像的行为总是保持它的比例。解决这个“行为”是使Button内容比它的高度更宽。如果Button内容宽度高于它的高度,则Binding将强制它的宽度更低。这会以某种方式使图像正常运行。

    在我的第二个例子中,添加例如:

    Margin="30 ,0" 
    

    To Image将解决它永无止境的增长问题。

    我不确定我是否对此做了很好的解释,如果您有可能改进此解释的建议,请发表评论。

答案 1 :(得分:0)

编辑: 好吧,我已经摆弄了你的代码,我可以确认按钮确实在增长无限大。我真的不能说为什么会这样。可能一些内部测量正在变得僵硬。我确实发现使用任何面板控件作为按钮内容(在这种情况下为Grid)将导致问题,StackPanel或DockPanel等也是如此。也许你最好不要将这些项目放在按钮中,而是使用其他控件。它真的需要一个按钮吗?

OLD:
按钮的高度不断变大,可能是因为网格单元本身不断变大。如果你使用网格分割器来调整网格组件的大小,那么按钮将假定它所在的单元格的整个高度。如果你要解释它变得越来越大的情况,那么它会更有意义“来吧想一想,如果这是一个驻留在物品控制中的东西,为什么首先是栅格分割器和空单元?

以上:
通过'现在将溢出高度继续变大'我假设你的意思是你的按钮的宽度和高度。那是因为你的宽度直接绑定到高度。

如果你的意思是'不会溢出......'这是另一个完全与网格行大小有关的故事。也许您应该澄清您的实际问题,并提供一些有效的XAML作为示例。 (帖子中的XAML缺少按钮内容中的''标记。