2013-02-06 1 views
1

ObservableCollection<Shape> (DrawingInstructions)에 바인딩하고 추가 할 모양을 Line으로 애니메이트하고자하는 MVVM을 사용하고 있습니다.WPF 데이터에 애니메이션을 적용하는 방법 라인 항목 (도형)

DoubleAnimation 종류의 방법으로 개별 선을 (X1, Y1)에서 (X2, Y2)까지 그려야합니다.

다음과 같은 변형을 시도했지만 작동하지 않습니다.

뷰 모델

<ItemsControl ItemsSource="{Binding Path=DrawingInstructions}"> 
<ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate > 
     <Canvas> 
      : 
     </Canvas> 
    </ItemsPanelTemplate> 
</ItemsControl.ItemsPanel> 
<ItemsControl.Triggers> 
    <EventTrigger RoutedEvent="Binding.TargetUpdated"> 
     <BeginStoryboard> 
      <Storyboard > 
       <DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Position" From="{Binding Path=X1}" To="{Binding Path=X2}"/> 
       <DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Position" From="{Binding Path=Y1}" To="{Binding Path=Y2}"/> 
      </Storyboard> 
     </BeginStoryboard>     
    </EventTrigger> 
</ItemsControl.Triggers> 

는 이름이 라인의 도면 지침에 추가되는 코드가 포함되어 있습니다.

var line = new Line 
{ 
    X1 = currentSituation.Position.X, 
    Y1 = currentSituation.Position.Y, 
    X2 = newSituation.Position.X, 
    Y2 = newSituation.Position.Y, 
    Name = "CurrentLine", 
    Stroke = brush, 
    StrokeThickness = 2 
}; 
drawingInstructions.Add(line); 

UPDATE : 작품 @Nico 제안

솔루션 - LineX1, X2, Y1, Y2TimeOffset 특성을 나타내는 "모델"클래스를 소개합니다. 애니메이션의 개별 속성을 사용하여 ObservableCollection<MyModelClass>에 데이터 바인딩 :

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <Line Name="CurrentLine" X1="{Binding X1}" Y1="{Binding Y1}" X2="{Binding X1}" Y2="{Binding Y1}" Stroke="Black" StrokeThickness="2"> 
      <Line.Triggers> 
       <EventTrigger RoutedEvent="Loaded"> 
        <BeginStoryboard> 
         <Storyboard > 
          <DoubleAnimation Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="X2" BeginTime="{Binding Path=TimeOffset}" From="{Binding Path=X1}" To="{Binding Path=X2}"/> 
          <DoubleAnimation Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Y2" BeginTime="{Binding Path=TimeOffset}" From="{Binding Path=Y1}" To="{Binding Path=Y2}"/> 
         </Storyboard> 
        </BeginStoryboard> 
       </EventTrigger> 
      </Line.Triggers> 
     </Line> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 
+0

'currentLine'은 정확히 무엇입니까? 이것은'System.Windows.Shapes.Line'입니까? 이 이름을 가진 속성이 없으므로이 객체에서 'Position' 속성을 애니메이션으로 만들 수 없습니다. Shape 클래스의 정의를 추가하십시오. –

+0

@Nico 죄송합니다, 당신 말이 맞아요. 'CurrentLine'은 (ViewModel 코드에서) ObservableCollection에 추가 된'Line'의 이름입니다. 이것을 반영하도록 질문을 수정하겠습니다. 이 접근법을'ValueConverter' ('Shape' ->'Line')에 대한 (가능한) 대안으로 사용하고 있습니다. – mhoff

답변

1

먼저 라인의 컬렉션에 ItemsControl에 바인딩과 선로를 표시 할 수 없습니다. 대신 필요한 속성이있는 모델 클래스를 만들어야합니다. 그렇지 않으면 WPF 오류가 발생합니다.

public class VM 
{ 
    public ObservableCollection<DrawingInstruction> DrawingInstructions { get; set; } 
} 

public class DrawingInstruction 
{ 
    public double X1 { get; set; } 
    public double X2 { get; set; } 
    public double Y1 { get; set; } 
    public double Y2 { get; set; } 
} 

그런 다음 이미 언급했듯이 애니메이션에서 X2 및 Y2 속성을 타겟팅해야합니다. 다음은 나를 위해 작동 한 XAML입니다.

<ItemsControl ItemsSource="{Binding DrawingInstructions}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate > 
      <Canvas/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Line Name="CurrentLine" X1="{Binding X1}" Y1="{Binding Y1}" Stroke="Black" StrokeThickness="2"> 
       <Line.Triggers> 
        <EventTrigger RoutedEvent="Loaded"> 
         <BeginStoryboard> 
          <Storyboard > 
           <DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="X2" From="{Binding Path=X1}" To="{Binding Path=X2}"/> 
           <DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Y2" From="{Binding Path=Y1}" To="{Binding Path=Y2}"/> 
          </Storyboard> 
         </BeginStoryboard> 
        </EventTrigger> 
       </Line.Triggers> 
      </Line> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate>    
</ItemsControl> 

컨트롤이로드되는 즉시 애니메이션이 시작됩니다. 나는 그것이 당신의 의도 였기를 바랍니다. 모든 항목에는 고유 한 애니메이션이 있으므로 ItemTemplate에 애니메이션을 추가해야합니다.

+0

DataTemplate for Lines와 DrawingInstruction에 대한 바인딩 라인 DTO는 매우 좋은 아이디어입니다! 나는 그것을 밖으로 시도하고 다시보고 (그리고 대답을 수락) – mhoff

+0

보고서를 가져 오는 데 너무 오래 걸려서 죄송합니다 - 이제 귀하의 솔루션을 허용으로 표시했습니다. 하지만,로드하는 동안 (제안한대로) 애니메이션을 트리거하는 데 문제가 있습니다. 그러나 관찰 가능한 컬렉션이 변경 될 때. 여러 가지 트리거 (EventTrigger, DataTrigger)를 사용하여 연결된 동작을 추가했지만 행운은 없었습니다. 데이터 바인딩 및 애니메이션 트리거를 모두 수행 할 수 없습니다. – mhoff

+0

당신은 하중을가 했습니까? 해당 항목이 컬렉션에 추가 될 때 선이 생성되고 애니메이션이 시작되기 때문입니다. 또는 항목을 추가하거나 제거 할 때 전체 콜렉션에서 애니메이션을 시작해야합니까? –

관련 문제