Silverlight 2 Beta 2 での Databind RenderTransform スケーリング
-
09-06-2019 - |
質問
Silverlight 2 Beta 2 でレンダリング変換の ScaleX と ScaleY をデータバインドできるかどうかを知っている人はいますか?WPF ではバインド変換が可能ですが、XAML を介して Silverlight でバインドを設定するとエラーが発生します。おそらくコードを通じてそれを行うことが可能でしょうか?
<Image Height="60" HorizontalAlignment="Right"
Margin="0,122,11,0" VerticalAlignment="Top" Width="60"
Source="Images/Fish128x128.png" Stretch="Fill"
RenderTransformOrigin="0.5,0.5" x:Name="fishImage">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
ScaleTransform要素のScaleXとScaleYをバインドしたいと思います。
データ コンテキストの double プロパティに対してバインドしようとすると、ランタイム エラーが発生します。
Message="AG_E_PARSER_BAD_PROPERTY_VALUE [Line: 1570 Position: 108]"
私のバインディングは次のようになります。
<ScaleTransform ScaleX="{Binding Path=SelectedDive.Visibility}"
ScaleY="{Binding Path=SelectedDive.Visibility}"/>
バインド パスが正しいことを 3 回確認しました。同じ値に対してスライドバーをバインドしていますが、それは問題なく動作します。
可視性は double 型で、0.0 ~ 30.0 の数値です。その数値を 0.5 と 1 にスケールダウンする値コンバーターがあります。水の透明度に応じて魚のサイズをスケールしたいのです。だから、私が束縛するタイプの問題ではないと思います...
解決
ScaleTransform にはデータ コンテキストがないため、バインディングはそれ自体から SelectedDive.Visibility を探していますが、見つからない可能性があります。Silverlight xaml とデータバインディングには、WPF とは異なる点がたくさんあります。
とにかくこれを解決するには、コード**でバインディングを設定するか、データオブジェクトのPropertyChangedイベントを手動でリッスンしてコードビハインドでスケールを設定する必要があります。
スケール変更のためのアニメーション/ストーリーボードを作成したい場合は、後者を選択します。
** 確認する必要がありますが、バインドできない可能性があります。私の記憶では、RenderTransform がアニメーションの一部ではない場合、行列変換に変換され、すべての賭けがオフになります。
他のヒント
それは実行時エラーですか、それともコンパイル時ですか、ジョナス?見てみると、 ドキュメンテーション, 、ScaleX と ScaleY は依存関係プロパティなので、次のように記述できるはずです。
<ScaleTransform ScaleX="{Binding Foo}" ScaleY="{Binding Bar}" />
...ここで、Foo と Bar は適切なタイプです。
編集:もちろん、それは WPF ドキュメントです。Silverlight で ScaleX と ScaleY を依存関係プロパティではなく標準プロパティに変更した可能性があると思います。発生しているエラーについて詳しくお聞きしたいです。
ああ、あなたの問題がわかった気がします。Visibility 型 (SelectedDive.Visibility) のプロパティを Double 型 (ScaleTransform.ScaleX) のプロパティにバインドしようとしています。WPF/Silverlight では、これら 2 つのタイプの間で変換できません。
何を達成しようとしていますか?XAML についてお手伝いできるかもしれません。「SelectedDive」とは何ですか?その可視性が変更されたときに何が起こりますか?
申し訳ありませんが、回答数を増やしたいと思っていたため、質問を編集してさらに詳しい情報を追加したことに気づきませんでした。
OK、Visibility のタイプは Double なので、バインディングはその点で機能するはずです。
回避策として、SelectedDive.Visibility がバインドされているスライダー コントロールに ScaleX と ScaleY の値を直接バインドしてみてはいかがでしょうか。何かのようなもの:
<ScaleTransform ScaleX="{Binding ElementName=slider1,Path=Value}" ... />
それがうまくいけば、少なくとも前進するでしょう。
編集:ああ、Silverlight はバインディングで ElementName 構文をサポートしていないため、機能しない可能性があると一度読んだことを思い出しました。
そうですね、埋め込まれたレンダリング変換が適用先のオブジェクトから DataContext を継承していない可能性があります。DataContext を強制的に挿入できますか?たとえば、変換に名前を付けます。
<ScaleTransform x:Name="myScaler" ... />
...そして、コードビハインドで次のようにします。
myScaler.DataContext = fishImage.DataContext;
...そのため、スケーラーはその DataContext をイメージと確実に共有します。
OK、イメージ自体は DataContext を適切に取得していますか?
これを追加してみてください:
<Image Tooltip="{Binding SelectedDive.Visibility}" ... />
コンパイルして実行できたら、画像の上にカーソルを置き、正しい値が表示されるかどうかを確認します。
XAML を通じてこれを解決したいと思っていましたが、Brian の提案が最善の方法であることがわかりました。Matt の提案に従って、コードからアクセスできるようにスケール変換に名前を付けました。次に、スライダーの値変更イベントをフックし、ScaleX プロパティと ScaleY プロパティを手動で更新しました。可視範囲 (0 ~ 30 m) からスケール (0.5 ~ 1) に変換する値コンバーターを維持しました。コードは次のようになります。
private ScaleConverter converter;
public DiveLog()
{
InitializeComponent();
converter = new ScaleConverter();
visibilitySlider.ValueChanged += new
RoutedPropertyChangedEventHandler<double>(visibilitySlider_ValueChanged);
}
private void visibilitySlider_ValueChanged(object sender,
RoutedPropertyChangedEventArgs<double> e)
{
fishScale.ScaleX = (double)converter.Convert(e.NewValue,
typeof(double), null, CultureInfo.CurrentCulture);
fishScale.ScaleY = fishScale.ScaleX;
}