2013-01-22 97 views
5

我有定义的标准WPF格栅2列为:限制最大宽度

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" MinWidth="200" /> 
     <ColumnDefinition Width="Auto" /> 
    </Grid.ColumnDefinitions> 
    ... 
</Grid> 

我想要实现的是,第二列被自动调整大小基于其内容和第一列获取所有剩余空间。不过,我也希望第一列永远不会少于200像素。问题是,使用这种配置,我的自动列将被切断,而不是被调整大小。

我真正想要的是WPF首先为第一列分配200个像素,然后占用所有剩余空间并请求第二列的内容以剩余宽度的最大大小限制自行调整大小。如果内容需要较少的空间,则应将剩余空间分配给第一列(使其大于200像素)。

使用案例:我的第二列是一个具有固定高宽比的图像,因此对于给定的高度,存在最佳宽度。我也有第一栏,其中一些控件应始终可见。如果有更多的空间可用,我希望将空间分配给第一列而不是第二列。

有没有一种方法来实现这与默认的WPF控件或我需要写我自己的网格呢?

回答

1

我看到第二列被切断的唯一时间是列2 + 200的宽度大于网格的宽度。我打得周围,也许这是你的解决方案:

<Grid Height="200" 
     Width="600"> 
    <Grid.ColumnDefinitions> 
    <ColumnDefinition Width="*" 
         MinWidth="200" /> 
    <ColumnDefinition Width="Auto" /> 
    </Grid.ColumnDefinitions> 
    <Border Background="Blue" 
      Grid.Column="0" /> 
    <Viewbox Grid.Column="1" 
      Stretch="Uniform" 
      MaxWidth="400"> 
    <Border Background="Yellow" 
      BorderBrush="Red" 
      BorderThickness="4" 
      Height="200" 
      Width="300" /> 
    </Viewbox> 
</Grid> 

我试着写<ColumnDefinition Width="Auto" MaxWidth="400"/>但maxwidth都没有效果呢。

视图框的最大宽度以总宽度计算 - 保留的200如果不明显。

+0

接下来的问题是:由于我不知道窗口大小决定之前的总宽度(600),因此如何计算网格的最大宽度?我想我可以为此编写一个转换器,但如果有更直接的方法,它会好很多... – aKzenT

+0

我不知道,但我会按照这个问题。我可以删除,如果你觉得它伤害你得到更好的答案的机会。我也不喜欢转换器。 –

+0

请不要删除答案。我想我已经有一个想法,如果没有基于你的版本的转换器解决这个问题。 – aKzenT

2

这听起来像你想要的基本上有2个不同的模式为您的第二列。当整个图像有足够的空间显示在当前的高度时,它应该是自动的,否则应该在获得第一列200后留下剩余空间。要进行这种模式切换,您可以使用转换器并将宽度绑定到列。

在这里,您有2个基本输入:可用于网格的总大小以及图像的所需宽度。既然你需要他们,你需要一个IMultiValueConverter。这是一个基本的实现来计算开关上述:

public class AutoColumnConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     double imageWidth = values.OfType<double>().FirstOrDefault(); 
     double gridWidth = values.OfType<double>().ElementAtOrDefault(1); 
     int minWidth = System.Convert.ToInt32(parameter); 

     double availableSpace = gridWidth - minWidth; 
     if (imageWidth > availableSpace) 
      return new GridLength(availableSpace, GridUnitType.Pixel); 

     return new GridLength(0, GridUnitType.Auto); 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

要使用这个你需要用你的网格中,你可以结合的,而不是网格本身,这将从根本上撒谎可用空间的另一个元素它并尝试用两个定义的列进一步扩展。这里我使用Source.Width来查找图像所需的宽度。如果您更关心宽高比或者想要考虑高度,您可能需要调整。

<Border> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" MinWidth="200" /> 
      <ColumnDefinition> 
       <ColumnDefinition.Width> 
        <MultiBinding ConverterParameter="200"> 
         <MultiBinding.Converter> 
          <local:AutoColumnConverter/> 
         </MultiBinding.Converter> 
         <Binding ElementName="Img" Path="Source.Width"/> 
         <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Border}}" Path="ActualWidth"/> 
        </MultiBinding> 
       </ColumnDefinition.Width> 
      </ColumnDefinition> 
     </Grid.ColumnDefinitions> 

     <Image x:Name="Img" Grid.Column="1" Stretch="Uniform" StretchDirection="DownOnly" 
       Source="..."/> 
    </Grid> 
</Border> 
+3

我想这会起作用,但说实话我真的厌倦了在WPF中编写数千个转换器。我希望能够提供一些开箱即用的东西。 – aKzenT