2009-08-10 3 views
1

Я ищу некоторые рекомендации по созданию WPF UserControl.WPF UserControl Dynamic Size/Dock/Anchor & StoryBoard

Моя цель - создать неопределенный индикатор выполнения, который перемещает изображение назад и вперед. Я хотел бы иметь возможность прикреплять левый и правый края этого пользовательского элемента управления к сторонам окна, поэтому, если пользователь изменяет размер окна, ширина полосы выполнения также увеличивается. Меня не волнует высота, которая может быть постоянной.

Вот что у меня есть, он отлично работает, за исключением случаев, когда я добавляю элемент управления в форму, я не могу установить параметры стыковки, и я не могу понять, как сделать анимацию раскадровки использовать полную ширину пользовательского контроля.

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    x:Class="WPFStyle.PGBProgress" 
    x:Name="MotionProgressBar" Width="550" Margin="5" Height="100" MinWidth="550" MinHeight="100" MaxWidth="550" MaxHeight="100"> 
    <UserControl.Resources> 
     <Storyboard x:Key="Motion" AutoReverse="True" RepeatBehavior="Forever"> 
      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"> 
       <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:01" Value="127"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:02" Value="242"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:03" Value="342"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:04" Value="433"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:07" Value="433"/> 
      </DoubleAnimationUsingKeyFrames> 
      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"> 
       <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:03" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:04" Value="-2"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:07" Value="-2"/> 
      </DoubleAnimationUsingKeyFrames> 
      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"> 
       <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:01" Value="89.705"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:02" Value="179.29"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:03" Value="270.032"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:04" Value="362.902"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:07" Value="717.969"/> 
      </DoubleAnimationUsingKeyFrames> 
     </Storyboard> 
    </UserControl.Resources> 
    <UserControl.Triggers> 
     <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
      <BeginStoryboard Storyboard="{StaticResource Motion}"/> 
     </EventTrigger> 
    </UserControl.Triggers> 

    <Grid x:Name="LayoutRoot"> 
     <Image x:Name="image" HorizontalAlignment="Left" Width="85.622" Source="image.png" Stretch="Fill" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Margin="0,0,0,0"> 
      <Image.RenderTransform> 
       <TransformGroup> 
        <ScaleTransform/> 
        <SkewTransform/> 
        <RotateTransform/> 
        <TranslateTransform/> 
       </TransformGroup> 
      </Image.RenderTransform> 
     </Image> 
    </Grid> 
</UserControl> 

ответ

1

Замените TranslateTransform.X анимации с этим:

<DoubleAnimation Storyboard.TargetName="image" 
       Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" 
       From="0" 
       To="{Binding ElementName=MotionProgressBar, Path=ActualWidth}" 
       Duration="0:0:7"/> 

Как вы можете видеть реальный трюк является обязательным; Я связываю свойство To с UserControl ActualWidth. Та же концепция может быть применена к вашим другим анимациям, даже с использованием KeyFrames (хотя я не нахожу, что KeyFrames немного проще).

Что касается «стыковки» Я думаю, что вы ищете,

HorizontalAlignment="Stretch" 

Это заставит ваш контроль, чтобы заполнить всю ширину она дана.

+0

Это прекрасно работает; однако, я понимаю теперь, что он оживляет изображение с правой стороны элемента управления sicne, он перемещает свойство X в фактическую ширину - есть ли простая привязка к (ActualWidth - image.Width)? – Nate

+0

Да, используйте конвертер для привязки. – Charlie

2

Стыковка не будет работать, потому что вы жестко закодировали размер Min/Max в элементе управления. Это плохо работает со стыковкой. И это связано с жестко кодированной анимацией, см. Ответ @ Charlie.

Итак, используйте только ограничение по размеру, которое действительно необходимо, например, в этом случае возможно MinHeight и MinWidth, но оставим открытым.