【问题标题】:How to Set Grid Column MaxWidth depending on Window or Screen Size in XAML如何在 XAML 中根据窗口或屏幕大小设置网格列 MaxWidth
【发布时间】:2010-09-10 02:04:15
【问题描述】:

我在一个窗口中有一个 3 列网格,第一列上有一个 GridSplitter。我想将第一列的 MaxWidth 设置为父窗口或页面 Width(或 ActualWidth)的三分之一,如果可能,我更愿意在 XAML 中执行此操作。

这是在 XamlPad(或类似的)中使用的一些示例 XAML,它显示了我在做什么。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="Column1" Width="200"/>
            <ColumnDefinition x:Name="Column2" MinWidth="50" />
            <ColumnDefinition x:Name="Column3" Width="{ Binding ElementName=Column1, Path=Width }"/>
            </Grid.ColumnDefinitions>

        <Label Grid.Column="0" Background="Green" />
        <GridSplitter Grid.Column="0" Width="5" />
        <Label Grid.Column="1" Background="Yellow" />
        <Label Grid.Column="2" Background="Red" />
    </Grid>
</Page>

如您所见,右列的宽度与第一列的宽度绑定,因此当您使用拆分器滑动左列时,右列的效果相同 :) 如果将左列向右滑动,最终它将滑过页面/窗口的一半并滑到窗口的右侧,推开第 2 列和第 3 列。

我想通过将第 1 列的 MaxWidth 设置为窗口宽度的三分之一(或类似的东西)来防止这种情况。我可以很容易地在后面的代码中做到这一点,但是如何在“仅 XAML”中做到这一点?

编辑: David Schmitt 建议使用 SharedSizeGroup 而不是绑定,这是一个很好的建议。我的示例代码将如下所示:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
        <Grid IsSharedSizeScope="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="Column1" SharedSizeGroup="ColWidth" Width="40"/>
                <ColumnDefinition x:Name="Column2" MinWidth="50" Width="*" />
                <ColumnDefinition x:Name="Column3" SharedSizeGroup="ColWidth"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Background="Green" />
            <GridSplitter Grid.Column="0" Width="5" />
            <Label Grid.Column="1" Background="Yellow" />
            <Label Grid.Column="2" Background="Red" />
        </Grid>
</Page>

【问题讨论】:

    标签: wpf xaml width actualwidth


    【解决方案1】:

    我认为仅 XAML 的方法有些迂回,但这里有一种方法。

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
          xmlns:sys="clr-namespace:System;assembly=mscorlib"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    
        <!-- This contains our real grid, and a reference grid for binding the layout-->
        <Grid x:Name="Container">
    
          <!-- hidden because it's behind the grid below -->
          <Grid x:Name="LayoutReference">
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*"/>
              <ColumnDefinition Width="*"/>
              <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <!-- We need the border, because the column doesn't have an ActualWidth -->
            <Border x:Name="ReferenceBorder" 
                    Background="Black" />
            <Border Background="White" Grid.Column="1" />
            <Border Background="Black" Grid.Column="2" />
          </Grid>
    
          <!-- I made this transparent, so we can see the reference -->
          <Grid Opacity="0.9">
              <Grid.ColumnDefinitions>
                  <ColumnDefinition x:Name="Column1" 
                                    MaxWidth="{Binding ElementName=ReferenceBorder,Path=ActualWidth}"/>
                  <ColumnDefinition x:Name="Column2" 
                                    MinWidth="50"  />
                  <ColumnDefinition x:Name="Column3" 
                                    Width="{ Binding ElementName=Column1, Path=Width }"/>
                  </Grid.ColumnDefinitions>
    
              <Label Grid.Column="0" Background="Green"/>
              <GridSplitter Grid.Column="0" Width="5" />
              <Label Grid.Column="1" Background="Yellow" />
              <Label Grid.Column="2" Background="Red" />
          </Grid>
        </Grid>
    
    </Page>
    

    【讨论】:

    • 请使用 SharedSizeGroup 而不是绑定到另一列的宽度!
    • 我在 XamlPad 中尝试了上面的 xaml,它的行为有点奇怪,但我明白你的意思!谢谢。
    【解决方案2】:

    懒得自己写了,但你应该能够使用数学转换器并绑定到你的父窗口宽度(通过名称,或使用 RelativeSource 祖先搜索)。

    //I know I borrowed this from someone, sorry I forgot to add a comment from whom
    public class ScaledValueConverter : IValueConverter
    {
      public Object Convert(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
      {
         Double scalingFactor = 0;
         if (parameter != null)
         {
            Double.TryParse((String)(parameter), out scalingFactor);
         }
    
         if (scalingFactor == 0.0d)
         {
            return Double.NaN;
         }
    
         return (Double)value * scalingFactor;
      }
    
      public Object ConvertBack(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
      {
         throw new Exception("The method or operation is not implemented.");
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-11
      相关资源
      最近更新 更多