3

我想将 scaleTransform 绑定到传递ActualWidthor的转换器ActualHeight

这是我想做的:

<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();
    }
}
4

3 回答 3

4

我认为您可能会想出一种方法来完成这项工作,方法是让 ScaleConverter 从 下降DependencyObject,给它一个 ActualSize 依赖属性,将它的两个实例而不是一个放在您的资源中,并进行单向源绑定将一个实例的 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 默认情况下没有自然大小。上面的代码片段设置了一个 Width 和 Height ,它将把你的椭圆放在拉伸的 Viewbox 的右下角;你可能想要一些不同的东西。

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

于 2009-06-27T21:04:58.597 回答
3

编辑:我的答案就是重构你的代码,以便它编译。如果您的解决方案不起作用,那么这也不起作用。

而不是使用IValueConverter, 使用IMultiValueConverterand MultiBinding。与其将额外的值作为 aConverterParameter传递,不如将其作为额外的绑定传递。

    <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();
    }
}
于 2013-03-21T16:05:41.417 回答
0

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

于 2009-06-27T18:31:03.313 回答