3

ActualWidthまたはを渡すコンバーターに scaleTransform をバインドしたいと思い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

DependencyObjectScaleConverter を から派生させ、ActualSize 依存関係プロパティを与え、そのインスタンスをリソースに 1 つではなく 2 つ配置し、一方向からソースへのバインディングを行うことで、おそらくこれを機能させる方法を見つけられると思います。 1 つのインスタンスの ActualSize をキャンバスの ActualSize にバインドし、もう 1 つのインスタンスをそのキャンバスにバインドします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 を割り当てる必要があります。上記のスニペットは、楕円を引き伸ばされたビューボックスの右下隅に配置する幅と高さを設定します。それとは違うものが欲しいかもしれません。

Viewbox の考えられる欠点の 1 つは、ストロークの太さもスケーリングされることです。そのため、ウィンドウを短く幅広にすると、水平方向のストロークは細くなり、垂直方向のストロークは太くなります。それが問題である場合は、データバインディングに固執する必要があるかもしれません。

于 2009-06-27T21:04:58.597 に答える
3

編集:私の答えは、コンパイルできるようにコードをリファクタリングすることだけです。ソリューションが機能しない場合、これも機能しません。

を使用する代わりに、と を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();
    }
}
于 2013-03-21T16:05:41.417 に答える