1

wpfCanvasクラスから派生した「MyCanvas」というカスタムクラスがあります。MyCanvasには、キャンバスのスケール変換を指定するDependencyプロパティ'Scale'があります。ここで、Scaleの値が変更されたら、古い値から新しい値への変換をアニメートしたいと思います。そのために私はLayoutTransform.BeginAnimation(...)メソッドを使用しています。

コード:

//This represents the time it will take to zoom
Duration zoomDuration = new Duration(TimeSpan.Parse("0:0:0.3"));

//Set up animation for zooming
DoubleAnimationUsingKeyFrames scaleAnimation = new DoubleAnimationUsingKeyFrames();
scaleAnimation.Duration = zoomDuration;
scaleAnimation.KeyFrames = GetAnimationSplines(newScale);
scaleAnimation.Completed += new EventHandler(
    (sender, e) => Scale = newScale);

// Start the scale (zoom) animations
LayoutTransform.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
LayoutTransform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

XMAL:

<Grid>
    <ItemsControl x:Name="Items">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <local:MyCanvas Scale="{Binding Scale, Mode=TwoWay}">
                    <local:MyCanvas.LayoutTransform UseLayoutRounding="True">
                        <ScaleTransform ScaleX="{Binding Scale, Mode=TwoWay}" 
                                        ScaleY="{Binding Scale, Mode=TwoWay}"/>
                    </local:MyCanvas.LayoutTransform>
                 </local:MyCanvas>
             </ItemsPanelTemplate>
         </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>

しかし、このコードを実行した後、ScaleXand ScaleYwith Scale(viewmodelのプロパティ)のバインドが壊れています。つまり、の値をScale変更しても、キャンバスのスケールは変更されません。

エラーメッセージ(スヌープを使用):

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Scale; DataItem=null; target element is 'ScaleTransform' (HashCode=796423); target property is 'ScaleX' (type 'Double')

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Scale; DataItem=null; target element is 'ScaleTransform' (HashCode=796423); target property is 'ScaleY' (type 'Double')

誰かがこれに対する解決策を持っているかどうか私に知らせてください。ありがとう

4

3 に答える 3

0

私もこれが起こったことを裏付けることができますが、私はまだきれいな解決策を見つけていません。回答の1つで説明したのと同じように、アニメーションの実行後にバインドされたオブジェクトに影響を与えないスライダーの変更についてのケースがありました(はい、アニメーションの「ホールド」を「解放」するようにFillBehavior設定Stopおよび/または実行しました)BeginAnimation(someProperty, null)プロパティ上で。アニメーション化後もプロパティを編集できることを示すために(ただし、バインディングのソースであるスライダーを使用せずに)、プロパティを特定の値に設定するボタンを設定しました。このボタンは実際に機能しました。アニメーションの後でそのプロパティを完全に変更します。特定のアニメーションの結果として、WPFのバインディングが壊れることがあるようです。

それほどクリーンではない回避策は、アニメーションのCompletedハンドラーのコードでバインディングを再確立することです。

于 2013-03-08T16:57:34.070 に答える
0

WPF Applicationこれは上記の問題の解決策ではありませんが、上記の問題を再現するための実用的なサンプルです。

XAML:

<Window x:Class="TestWpfApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>

    <Grid Grid.Row="0">
        <Grid.LayoutTransform>
            <ScaleTransform ScaleX="{Binding ElementName=zoomer, Path=Value}" ScaleY="{Binding ElementName=zoomer, Path=Value}" x:Name="scaleTx" />
        </Grid.LayoutTransform>

        <Border Background="Aqua" BorderThickness="3" BorderBrush="Blue" Height="50" Width="50" />
    </Grid>
    <StackPanel Orientation="Horizontal" Grid.Row="1">
        <Slider x:Name="zoomer" Width="200" Value="1" Minimum="0.1" Maximum="3" TickFrequency="0.1" IsSnapToTickEnabled="True" Margin="3"/>
        <Button Content="Animate" Click="Button_Click" Margin="3"/>
    </StackPanel>
</Grid>

コード:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

        //This represents the time it will take to zoom
        Duration zoomDuration = new Duration(TimeSpan.Parse("0:0:0.5"));

        //Set up animation for zooming
        DoubleAnimationUsingKeyFrames scaleAnimation = new DoubleAnimationUsingKeyFrames();
        scaleAnimation.Duration = zoomDuration;
        scaleAnimation.KeyFrames = GetAnimationSplines(zoomer.Maximum);

        scaleTx.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
        scaleTx.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);
    }

    /// <summary>
    /// This creates a spline for zooming with non-linear acceleration patterns.
    /// </summary>
    /// <param name="moveTo"></param>
    /// <returns></returns>
    protected DoubleKeyFrameCollection GetAnimationSplines(double moveTo)
    {
        DoubleKeyFrameCollection returnCollection = new DoubleKeyFrameCollection();

        returnCollection.Add(new LinearDoubleKeyFrame(moveTo, KeyTime.FromPercent(1.0)));

        return returnCollection;
    }
}

The shape in the center of window will scale when slide is moved. Once you click animate button to apply animation, the zooming will animate but after that slider stops working.

于 2012-03-27T11:08:39.990 に答える
0

さて、今日私は何かを試していましたが、突然問題が解決しました。それがどのように機能し始めるのか理解できませんでした。以前にも試したコードに次の変更を加えました。

scaleAnimation.FillBehavior = FillBehavior.Stop;

誰でも私にこれを説明できますか。ありがとう。

于 2012-03-29T04:36:43.260 に答える