【问题标题】:WPF/XAML bind width of an element to a fraction of screen sizeWPF/XAML 将元素的宽度绑定到屏幕大小的一小部分
【发布时间】:2011-04-05 13:06:57
【问题描述】:

我正在用 C#/WPF 编写一个应用程序,并试图弄清楚如何将网格列定义的宽度数据绑定到屏幕宽度的一小部分。这可能吗?基本上我想要这样的东西:

网格 = 2x2
第 1 行高度 = 屏幕高度的 2/3
第 2 行高度 = 屏幕高度的 1/3
第 1 行宽度 = 屏幕宽度的 2/3
第 2 行宽度 = 屏幕宽度的 1/3

认为这正确地将全宽绑定到列定义:

<ColumnDefinition Width="{Binding ElementName=Window1, Path=Width}"/>

但我不知道该怎么做是对它通过数据绑定获得的值执行操作......这甚至可能吗?我觉得这是我应该能够将代码写入 XAML 而不必以编程方式实现的东西,但我对 UI 设计的经验很少:( 我想要类似的东西:

<ColumnDefinition Width="{Binding ElementName=Window1, Path=Width} * 2 / 3"/>

但那是无效的

我是否应该只编写一个函数来在屏幕调整大小时重新布局 UI 元素?我觉得那是多余的......或者有一些我不知道的简单方法吗?欢迎任何输入!谢谢!

【问题讨论】:

    标签: c# wpf data-binding xaml


    【解决方案1】:

    听起来你只想使用星号:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
    

    这将始终为第一行提供 2/3 的高度和第二行的 1/3 的高度,以及第一列的 2/3 的宽度和第二列的 1/3 的宽度。它将基于 Grid 的大小,但如果 Grid 是 Window 的唯一子级,那么它将与 Window 的大小相同。

    【讨论】:

      【解决方案2】:

      我遇到了一种情况,我需要将控件的 width 绑定到另一个控件的 height 的一小部分,但我认为没有一个方便的内置控件-以这样划分绑定属性的方式。我最终制作了一个转换器,它将一个边界值除以转换器参数来解决这个问题,而无需求助于代码隐藏,并认为我会分享它,以防它有助于节省其他人一些时间。我在这里发布它是因为这篇文章是我在搜索是否有更清洁的方式时的第一个结果。

      转换器类:

      [ValueConversion(typeof(double), typeof(double))]
      public class DoubleDivisionConverter : System.Windows.Data.IValueConverter
      {
          public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              if(value == null) { return 0.0; }
              if(parameter == null) { return value; }
      
              double param;
              if(Double.TryParse(parameter.ToString(), out param))
              {
                  if(param == 0) { return 0.0; }
                  return (double)value / param;
              }
              else
              {
                  throw new ArgumentException("Could not parse converter parameter as double.");
              }
          }
      
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              if(value == null) { return 0.0; }
              if(parameter == null) { return value; }
      
              double param;
              if(Double.TryParse(parameter.ToString(), out param))
              {
                  if(param == 0) { return 0.0; }
                  return (double)value * param;
              }
              else
              {
                  throw new ArgumentException("Could not parse converter parameter as double.");
              }
          }
      }
      

      XAML:(UniformGrid Width 属性上使用的转换器)

      <Window.Resources>
          <converters:DoubleDivisionConverter x:Key="DoubleDivisionConverter"/>
      </Window.Resources>
      
      <Grid x:Name="sampleGrid">
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*"/>
              <ColumnDefinition Width="Auto"/>
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
              <RowDefinition Height="*"/>
          </Grid.RowDefinitions>
          <Grid.Resources>
              <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
                  <Setter Property="VerticalAlignment" Value="Center"/>
                  <Setter Property="HorizontalAlignment" Value="Center"/>
                  <Setter Property="FontSize" Value="18"/>
                  <Setter Property="FontWeight" Value="Bold"/>
              </Style>
          </Grid.Resources>
      
          <Border x:Name="rSample" Grid.Column="0" Grid.Row="0" Background="PaleVioletRed">
              <TextBlock>
                  <TextBlock.Inlines>
                      <Run Text="{Binding ElementName=rSample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=rSample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
                  </TextBlock.Inlines>
              </TextBlock>
          </Border>
      
          <!-- Set the UniformGrids width to 1/3 the height of the parent grid using the converter -->
          <UniformGrid Grid.Column="1" Grid.Row="0" Columns="1"
          Width="{Binding ElementName=sampleGrid, Path=ActualHeight, Converter={StaticResource DoubleDivisionConverter}, ConverterParameter=3, Mode=OneWay}">
              <Border x:Name="gSample" Background="LightGreen">
                  <TextBlock>
                      <TextBlock.Inlines>
                          <Run Text="{Binding ElementName=gSample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=gSample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
                      </TextBlock.Inlines>
                  </TextBlock>
              </Border>
              <Border x:Name="ySample" Background="LightGoldenrodYellow">
                  <TextBlock>
                      <TextBlock.Inlines>
                          <Run Text="{Binding ElementName=ySample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=ySample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
                      </TextBlock.Inlines>
                  </TextBlock>
              </Border>
              <Border x:Name="bSample" Background="LightBlue">
                  <TextBlock>
                      <TextBlock.Inlines>
                          <Run Text="{Binding ElementName=bSample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=bSample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
                      </TextBlock.Inlines>
                  </TextBlock>
              </Border>
          </UniformGrid>
      </Grid>
      

      结果:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-15
        • 1970-01-01
        • 2016-10-07
        • 2022-09-23
        • 2013-04-01
        • 2011-07-10
        • 2011-02-13
        相关资源
        最近更新 更多