2012-03-15 5 views
1

Я пытаюсь анимировать несколько фигур в визуальной маске, но когда я выполняю поворот формы «пульс». Я предполагаю, что по мере того, как формы вращаются, ограничивающие прямоугольники заставляют проходить макет. Однако, поскольку я использую RenderTransform, я не ожидал, что это вызовет изменения макета.RenderTransform в WPF, вызывающий непредвиденные изменения макета

Этот код иллюстрирует проблему:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="200" Width="200"> 
<StackPanel> 
    <Border BorderBrush="Red" BorderThickness="1" 
      Height="100" Width="100"> 
     <Border.Triggers> 
      <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
       <BeginStoryboard> 
        <Storyboard RepeatBehavior="Forever" > 
         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="inner_Ellipse" 
          Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"> 
          <LinearDoubleKeyFrame KeyTime="0:0:3" Value="-360"/> 
         </DoubleAnimationUsingKeyFrames> 
        </Storyboard> 
       </BeginStoryboard> 
       <BeginStoryboard> 
        <Storyboard RepeatBehavior="Forever" > 
         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse" 
          Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">            
          <LinearDoubleKeyFrame KeyTime="0:0:3" Value="360"/> 
         </DoubleAnimationUsingKeyFrames> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
     </Border.Triggers> 
     <Border.Background> 
      <VisualBrush Stretch="Uniform"> 
       <VisualBrush.Visual>      
        <Canvas Width="20" Height="20"> 
         <Ellipse x:Name="outer_Ellipse" 
           Stroke="Blue" StrokeThickness="1" 
           Width="20" Height="20" 
           RenderTransformOrigin="0.5,0.5"> 
          <Ellipse.RenderTransform> 
            <RotateTransform/> 
          </Ellipse.RenderTransform> 
         </Ellipse> 
         <Ellipse x:Name="inner_Ellipse" 
            Stroke="Red" StrokeThickness="1" 
            Width="18" Height="18" 
            Margin="1,1,0,0" 
            RenderTransformOrigin="0.5,0.5"> 
          <Ellipse.RenderTransform> 
            <RotateTransform/> 
          </Ellipse.RenderTransform> 
         </Ellipse> 
        </Canvas> 
       </VisualBrush.Visual> 
      </VisualBrush> 
     </Border.Background> 
    </Border> 
</StackPanel> 

Это простой образец гораздо более сложного приложения, в котором я использую Визуальное Кисти для украшения 2d плоскости манипулируют в 3d. Все работает хорошо, пока я не попробую и не анимирую кисти. Я пробовал несколько разных подходов, но всегда, похоже, сталкивался с этой проблемой макета.

Любые предложения оценены.

Благодаря

Роб

ответ

0

Ну, после большого количества проб и ошибок у меня есть рабочее решение. Содержимый визуала масштабироваться и не вызывают проблемы габаритов:

<Window x:Class="WpfApplication1.MainWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    SizeToContent="WidthAndHeight" > 
<StackPanel> 
    <Border BorderBrush="Black" BorderThickness="1" 
     Height="400" Width="400"> 
     <Border.Triggers> 
      <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
       <BeginStoryboard> 
        <Storyboard RepeatBehavior="Forever" > 
         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="inner_Ellipse" 
         Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"> 
          <LinearDoubleKeyFrame KeyTime="0:0:3" Value="-360"/> 
         </DoubleAnimationUsingKeyFrames> 
        </Storyboard> 
       </BeginStoryboard> 
       <BeginStoryboard> 
        <Storyboard RepeatBehavior="Forever" > 
         <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse" 
         Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"> 
          <LinearDoubleKeyFrame KeyTime="0:0:3" Value="360"/> 
         </DoubleAnimationUsingKeyFrames> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
     </Border.Triggers> 

     <Border.Background> 
      <VisualBrush Stretch="UniformToFill"> 
       <VisualBrush.Visual> 
        <Border BorderBrush="Transparent" BorderThickness="1" 
          Width="200" Height="200"> 
         <StackPanel Width="200" Height="200"> 
          <Canvas> 
           <Rectangle x:Name="outer_Ellipse" 
             Stroke="Blue" StrokeThickness="1" 
             Width="20" Height="200" 
              Canvas.Left="40" 
             RenderTransformOrigin="0.5,0.5"> 
            <Rectangle.RenderTransform> 
             <RotateTransform/> 
            </Rectangle.RenderTransform> 
           </Rectangle> 
           <Ellipse x:Name="inner_Ellipse" 
             Stroke="Red" StrokeThickness="1" 
             StrokeDashArray="2" 
             Canvas.Top="30" 
             Canvas.Left="20" 
             Width="200" Height="200" 
             RenderTransformOrigin="0.5,0.5"> 
            <Ellipse.RenderTransform> 
             <RotateTransform/> 
            </Ellipse.RenderTransform> 
           </Ellipse> 
          </Canvas> 
         </StackPanel> 
        </Border> 
       </VisualBrush.Visual> 
      </VisualBrush> 
     </Border.Background> 
    </Border> 
</StackPanel> 
</Window> 

«тайна», как представляется, обернув полотно, содержащее содержимое кисти в StackPanel и оборачивать это в кайме. (вместо StackPanel также будут работать Grid, DockPanel и WrapPanel).

     <Border BorderBrush="Transparent" BorderThickness="1" 
          Width="200" Height="200"> 
         <StackPanel Width="200" Height="200"> 

Граница должна иметь набор BorderBrush и BorderThickness. Также они должны иметь явную ширину и высоту. Здесь я задал значения, соответствующие содержимому, поэтому он масштабируется правильно.

Без всех трех этих компонентов возникает проблема с рамкой. Ясно, что что-то о правилах компоновки контейнеров имеет значение, но я понятия не имею, что и почему.

Ни в коем случае не удовлетворительное решение, и я был бы признателен, если кто-нибудь сможет осветить то, что здесь происходит.

По крайней мере, он работает как в приведенном выше демоверсии, так и в моем основном приложении, так или иначе!

Роб

2

я был в состоянии отследить причину вашей проблемы. Это связано с настройкой свойства Stretch="Uniform" на вашем VisualBrush. Кажется, что структура вычисляет ограничивающий прямоугольник на вашем VisuaBrush.Visual, а затем растягивает его до Border.Background. Следующий код должен иллюстрировать поведение. Я вынул свой inner_Ellipse и добавил outer_Rectangle, который должен имитировать ограничивающий прямоугольник растягивается:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="200" Width="200"> 
    <StackPanel> 
     <Border BorderBrush="Red" BorderThickness="1" 
      Height="100" Width="100"> 
      <Border.Triggers> 
       <EventTrigger RoutedEvent="FrameworkElement.Loaded">     
        <BeginStoryboard> 
         <Storyboard RepeatBehavior="Forever" > 
          <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Rectangle" 
          Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"> 
           <LinearDoubleKeyFrame KeyTime="0:0:6" Value="360"/> 
          </DoubleAnimationUsingKeyFrames> 
         </Storyboard> 
        </BeginStoryboard> 
        <BeginStoryboard> 
         <Storyboard RepeatBehavior="Forever" > 
          <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse" 
          Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"> 
           <LinearDoubleKeyFrame KeyTime="0:0:6" Value="360"/> 
          </DoubleAnimationUsingKeyFrames> 
         </Storyboard> 
        </BeginStoryboard> 
       </EventTrigger> 
      </Border.Triggers> 
      <Border.Background> 
       <VisualBrush Stretch="Uniform"> 
        <VisualBrush.Visual> 
         <Canvas Width="20" Height="20"> 
          <Ellipse x:Name="outer_Ellipse" 
           Stroke="Blue" StrokeThickness="1" 
           Width="20" Height="20" 
           RenderTransformOrigin="0.5,0.5"> 
           <Ellipse.RenderTransform> 
            <RotateTransform/> 
           </Ellipse.RenderTransform> 
          </Ellipse> 
          <Rectangle x:Name="outer_Rectangle" 
           Stroke="Blue" StrokeThickness="1" 
           Width="20" Height="20" 
           RenderTransformOrigin="0.5,0.5"> 
           <Rectangle.RenderTransform> 
            <RotateTransform/> 
           </Rectangle.RenderTransform> 
          </Rectangle> 
         </Canvas> 
        </VisualBrush.Visual> 
       </VisualBrush> 
      </Border.Background> 
     </Border> 
    </StackPanel> 
</Window> 

Что касается решения проблемы, и я не уверен. Один из способов - использовать Stretch="None" на вашем VisualBrush, но это не кажется идеальным, потому что тогда вам приходится иметь дело с размером вашего содержимого VisualBrush.Visual.

+0

Да, я знал, что отключив растяжку установил его, предполагая, что внутреннее содержание не больше, чем объект визуала быть применен. Ваш пример, вероятно, лучше иллюстрирует проблему.Проблема заключается в моем «содержании», потому что кисть исходит из наборов данных, а растяжка - правильное поведение в зависимости от размера оформляемого элемента управления. В принципе, я хочу, чтобы визуал «заклинился» сзади, если в этом случае он превосходит ограничительную рамку границы. благодаря – rjw