【问题标题】:WPF - Binding and RenderTransformWPF - 绑定和渲染转换
【发布时间】:2009-06-27 18:06:33
【问题描述】:

我想将 scaleTransform 绑定到传递 ActualWidthActualHeight 的转换器。

这是我想做的:

<Canvas x:Name="Canevas">
   <Canvas.RenderTransform>
      <TransformGroup>
         <ScaleTransform 
              ScaleX="{Binding RelativeSource={RelativeSource FindAncestor, 
                               AncestorType={x:Type UIElement}}, 
                               Path=ActualWidth, Mode=OneWay, 
                               Converter={StaticResource ScaleConverter}, 
                               ConverterParameter={Binding Path=ActualWidth}"

              ScaleY="{Binding RelativeSource={RelativeSource FindAncestor,
                               AncestorType={x:Type UIElement}}, 
                               Path=ActualHeight, Mode=OneWay, 
                               Converter={StaticResource ScaleConverter},  
                               ConverterParameter={Binding Path=ActualHeight}}"
         />
      </TransformGroup>
   </Canvas.RenderTransform>

   <Ellipse Canvas.Left="47" Canvas.Top="48" Height="155" 
            Name="ellipse1" Stroke="Black" Width="174" Fill="#FF00C6C3" />

问题是这不能编译:

ConverterParameter={Binding Path=ActualHeight}

所以我想知道如何将这些属性作为我的转换器的参数移动?是否可以在完整的 Xaml 中解决?

非常感谢您的帮助!

转换器源代码:

public class ScaleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
                                        System.Globalization.CultureInfo culture)
    {
        double v = (double)value;
        var actualSize = (double)parameter; //ActualWidth, ActualHeight

        var vScale = v * (1 + (v / actualSize));

        return vScale;
    }

    public object ConvertBack(object value, Type targetType, object parameter, 
                                        System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

【问题讨论】:

  • 你能显示你的转换器的代码吗?为什么需要 ConverterParameter ?也许你应该使用 MultiBinding 和 IMultiValueConverter...
  • 我添加了转换器源代码
  • 我不确定我是否理解你想要做什么......转换器应该返回一个比例因子,但根据你的公式它将返回一个宽度(或高度)。你到底想达到什么目的?

标签: wpf xaml binding actualwidth actualheight


【解决方案1】:

我认为您可能会想出一种方法来完成这项工作,方法是让 ScaleConverter 从 DependencyObject 下降,给它一个 ActualSize 依赖属性,将它的两个实例而不是一个放在你的资源中,然后做一个 - way-to-source 绑定将一个实例的 ActualSize 绑定到画布的 ActualWidth 并将另一个绑定到其 ActualHeight (因此当画布调整大小时,实例的 ActualSize 始终与画布的宽度/高度保持同步)。

然而,看起来您实际上可能想要一些简单的东西:拉伸画布以填充其父级。如果是这样,请看Viewbox

<Viewbox Stretch="Fill">
    <Canvas Width="221" Height="203">
        <Ellipse Canvas.Left="47" Canvas.Top="48" Height="155"
                 Stroke="Black" Width="174" Fill="#FF00C6C3" />
    </Canvas>
</Viewbox>

我添加了Stretch="Fill" 以在不保留纵横比的情况下同时拉伸 X 和 Y,因为这看起来就像您所追求的那样。您还需要为 Canvas 分配 Width 和 Height 以使其正常工作,因为 Canvas 默认情况下没有自然大小。上面的 sn-p 设置了一个 Width 和 Height ,它将把你的椭圆放在拉伸的 Viewbox 的右下角;你可能想要一些不同的东西。

Viewbox 的一个可能缺点是笔画粗细也会按比例缩放,因此如果您将窗口设置得又短又宽,则水平笔画会很细,而垂直笔画会很粗。如果这是个问题,您可能需要坚持使用数据绑定。

【讨论】:

    【解决方案2】:

    编辑: 我所做的只是重构您的代码,使其能够编译。如果您的解决方案不起作用,那么这也不起作用。

    不要使用IValueConverter,而是使用IMultiValueConverterMultiBinding。不要将该额外值作为ConverterParameter 传递,而是将其作为额外绑定传递。

        <Canvas x:Name="Canvas">
            <Canvas.RenderTransform>
                <TransformGroup>
                    <!--<ScaleTransform ScaleX="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UIElement}}, Path=ActualWidth, Mode=OneWay, Converter={StaticResource ScaleConverter}, ConverterParameter={Binding Path=ActualWidth}"
                               ScaleY="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UIElement}}, Path=ActualHeight, Mode=OneWay, Converter={StaticResource ScaleConverter}, ConverterParameter={Binding Path=ActualHeight}}" />-->
                    <ScaleTransform>
                        <ScaleTransform.ScaleX>
                            <MultiBinding Converter="{StaticResource ScaleConverter}">
                                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type UIElement}}" Path="ActualWidth" Mode="OneWay"/>
                                <Binding Path="ActualWidth"/>
                            </MultiBinding>
                        </ScaleTransform.ScaleX>
                        <ScaleTransform.ScaleY>
                            <MultiBinding Converter="{StaticResource ScaleConverter}">
                                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type UIElement}}" Path="ActualHeight" Mode="OneWay"/>
                                <Binding Path="ActualHeight"/>
                            </MultiBinding>
                        </ScaleTransform.ScaleY>
                    </ScaleTransform>
                </TransformGroup>
            </Canvas.RenderTransform>
            <Ellipse Canvas.Left="47" Canvas.Top="48" Height="155" Name="ellipse1" Stroke="Black" Width="174" Fill="#FF00C6C3" />
        </Canvas>
    

    还有你的转换器:

    public class ScaleConverter : IMultiValueConverter
    {
    
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double v = (double)values[0];
            var actualSize = (double)values[1]; //ActualWidth, ActualHeight
    
            var vScale = v * (1 + (v / actualSize));
    
            return vScale;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

      【解决方案3】:

      不幸的是,我认为这是不可能的。由于Binding.ConverterParameter 不是DependencyProperty,因此您不能使用绑定来填充其值。我之前尝试过这样做(使用ConverterParameter 的绑定)并遇到了与您相同的问题。

      【讨论】:

      • 我相信你可以使用反向绑定(例如使用 OneWayToSource)
      猜你喜欢
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 2022-10-24
      相关资源
      最近更新 更多