【问题标题】:WPF binding Width to Parent.Width*0.3WPF 将宽度绑定到 Parent.Width*0.3
【发布时间】:2013-12-18 01:40:02
【问题描述】:

我想将控件的宽度绑定到父控件的宽度,但要绑定到一定的比例。有没有办法做这样的事情:

<Rectangle  Name="rectangle1" Width="{Binding ActualWidth*0.3, ElementName=thumbnailCanvas, UpdateSourceTrigger=PropertyChanged}" Height="{Binding ActualHeight, ElementName=thumbnailCanvas, UpdateSourceTrigger=PropertyChanged}"/>

【问题讨论】:

  • 为什么不简单地使用具有适当大小列的网格?

标签: wpf data-binding scale


【解决方案1】:

您可以从https://github.com/omeraziz/NoTextOverflowWPF 下载示例。它看起来像一个 hack,但它确实有效!

<Window Title="NoTextOverflow"
    x:Class="NoTextOverflow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="Auto" Height="Auto"
    ResizeMode="CanResize" SizeToContent="WidthAndHeight">

<!--
    There is no fixed width in any of the UI elements including window, Label, TextBlock, TextBox etc.
    Window's SizeToContent grows and shrinks with the contents.
-->

<Grid Margin="10" ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Label VerticalAlignment="Center" Content="Type Here:" />
    <TextBox x:Name="LongText"
             Grid.Column="1" Grid.ColumnSpan="2"
             Width="{Binding ElementName=WidthRestrictorGrid, Path=ActualWidth, Mode=OneWay}"
             MinWidth="100"
             Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center"
             Text="Type here a long message and resize this window" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" />

    <!--
        This grid is used to calculate width of middle two columns.
        Remove this and its references to see the effect without this grid.
        Since this is not parent of TextBox and TextBlock so it must have a Name to bind with its Actualwidth
    -->

    <Grid x:Name="WidthRestrictorGrid"
          Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"
          Margin="10,1" HorizontalAlignment="Stretch" />

    <TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
               Width="{Binding ElementName=WidthRestrictorGrid, Path=ActualWidth, Mode=OneWay}"
               MinWidth="50"
               Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top"
               Background="LightGray"
               Text="{Binding ElementName=LongText, Path=Text}"
               TextWrapping="Wrap" />

    <Button Grid.Row="2" Grid.Column="3"
            Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom"
            Content="Dummy" />

</Grid>

【讨论】:

    【解决方案2】:

    也许您可以像这样添加比例变换:

    <Rectangle  Name="rectangle1" Width="{Binding ActualWidth, ElementName=thumbnailCanvas, UpdateSourceTrigger=PropertyChanged}" Height="{Binding ActualHeight, ElementName=thumbnailCanvas, UpdateSourceTrigger=PropertyChanged}">
        <Rectangle.RenderTransform>
            <ScaleTransform ScaleX="0.3" ></ScaleTransform>
        </Rectangle.RenderTransform>
    </Rectangle>
    

    【讨论】:

      【解决方案3】:

      当然可以,但您需要使用转换器。像这样的:

      using System;
      using System.Globalization;
      using System.Windows.Data;
      using System.Windows.Markup;
      
      namespace WpfTestBench.Converters
      {
          public class PercentageConverter : MarkupExtension, IValueConverter
          {
              private static PercentageConverter _instance;
      
              #region IValueConverter Members
      
              public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
              {
                  return System.Convert.ToDouble(value) * System.Convert.ToDouble(parameter);
              }
      
              public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
              {
                  throw new NotImplementedException();
              }
      
              #endregion
      
              public override object ProvideValue(IServiceProvider serviceProvider)
              {
                  return _instance ?? (_instance = new PercentageConverter());
              }
          }
      }
      

      您的 XAML 将如下所示:

      <Window x:Class="WpfTestBench.ScaleSample"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:converters="clr-namespace:WpfTestBench.Converters"
              Title="Scale sample" Height="300" Width="300">
          <Grid Name="ParentGrid">
              <Rectangle
                  Width="{Binding Path=ActualWidth, ElementName=ParentGrid, Converter={converters:PercentageConverter}, ConverterParameter='0.5'}"
                  Stroke="Black" StrokeThickness="2" />
          </Grid>
      </Window>
      

      【讨论】:

      • 请注意,“使用 ToDouble(String) 方法等同于将值传递给 Double.Parse(String) 方法,值是通过使用 当前线程的格式约定来解释的”文化"
      • 我想在我的应用程序中添加类似的东西,但是当我尝试实现(包括直接复制)时,我收到错误[名称空间“clr-中不存在名称“PercentageConverter” namespace:WpfTestBench.Converters"] 复制到我的应用程序中,完全按照你写的那样,它确实存在。
      【解决方案4】:

      我建议在 XAML 中使用网格列和 * 宽度类型简单地执行此操作:

      <Window x:Class="NameSpace.WindowName"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Title="Window1" Height="300" Width="300">
          <Grid>
              <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="*" />
                  <ColumnDefinition Width="2*" />
              </Grid.ColumnDefinitions>
      
              <Grid Grid.Column="0"></Grid><!--This item take up 1/3 of window width-->
              <Grid Grid.Column="1"></Grid> <!--This item take up remaining 2/3 of window width-->
      
          </Grid>
      </Window>
      

      您可以通过更改列宽中 * 之前的数字来更改列占用的比例。这里设置为 1 和 2,因此网格将被分成 3(所有 * 宽度的总和),其中 1/3 的宽度为第一列,2/3 为第二列。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-17
        • 2019-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-17
        • 2015-12-14
        • 1970-01-01
        相关资源
        最近更新 更多