2012-03-26 35 views
1

我有一個自定義類,說'MyCanvas'派生自wpf Canvas類。 MyCanvas具有指定畫布的比例變換的依賴屬性「比例」。現在當縮放比例的值發生變化時,我想要將變換從舊值轉換爲新值。因爲我正在使用LayoutTransform.BeginAnimation(...)方法。ScaleX和ScaleY上的LayoutTransform動畫正在與它們斷開綁定

代碼:

//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> 

但是執行此代碼,的ScaleXScaleYScale(在視圖模型的特性)的結合後是打破即改變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')

請讓我知道如果任何人有解決這一點。謝謝

+0

您在哪裏爲ScaleTransform屬性分配了ScaleTransform?請顯示該代碼。或者你不是? – Clemens 2012-03-26 07:56:38

回答

0

好了,今天我是想一些事情,突然的問題得到了解決。我不明白它是如何開始工作的。我對代碼進行了以下更改,我之前也嘗試過這些代碼。

scaleAnimation.FillBehavior = FillBehavior.Stop; 

任何人都可以向我解釋這一點。謝謝。

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.

0

我可以證實我也有過這種情況,但我還沒有找到一個乾淨的解決方案。我有一個案例,就像你在其中一個答案中描述的那樣 - 關於滑塊更改在動畫運行後不會影響綁定對象(是的,我將FillBehavior設置爲Stop和/或運行BeginAnimation(someProperty, null)以「釋放」動畫的爲了說明我仍然可以在動畫之後編輯屬性(但不是使用作爲綁定源的滑塊),我設置了一個按鈕,將該屬性設置爲特定值。實際上完美的工作是在動畫完成後改變屬性,似乎在某些情況下,WPF的綁定可能會因爲某些動畫而中斷。

一個不太乾淨的解決方法可能是重新建立代碼中的綁定在動畫的Completed處理程序中。