WPF TextBlock动画闪烁不起作用

时间:2018-12-18 09:56:09

标签: c# wpf mvvm storyboard .net-3.5

我有一个WPF TextBlock。 TextBlock绑定到MVVM布尔属性。我试图使其是否可见,并根据此MVVM布尔属性值闪烁。如果为真,则使其可见并显示TextBlock闪烁(我开始演示图板动画),否则,使其不可见且不闪烁,并停止演示图板动画。下面的代码不起作用。有什么问题吗?

class MyPhotoCaptureDelegate: NSObject, AVCapturePhotoCaptureDelegate {
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        // crop image
        if let cgImage = photo.cgImageRepresentation()?.takeUnretainedValue() {
            let cropRect : CGRect = calculateAspectRatioCrop(cgImage:cgImage, aspectRatio:16.0/9.0)
            if let cgCroppedImage = cgImage.cropping(to:cropRect) {
                let image = UIImage(cgImage:cgCroppedImage)
                if let photoData = image.jpegData(compressionQuality: 0.9) {
                    // add meta data from original image to cropped image data
                    self.photoData = addImageProperties(imageData: photoData, properties: photo.metadata as NSDictionary)
                }
            }
        }
    }

    func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) {
        if let error = error {
            print("Error capturing photo: \(error)")
            return
        }

        guard let photoData = photoData else {
            print("No photo data resource")
            return
        }
        savePhotoData()
    }

    func calculateAspectRatioCrop(cgImage : CGImage, aspectRatio: CGFloat) -> CGRect {
        var width = CGFloat(cgImage.width)
        var height = CGFloat(cgImage.height)
        // should be cropped vertically or horizontally?
        if aspectRatio > width/height {
            height = width / aspectRatio
        } else {
            width = height * aspectRatio
        }
        return CGRect(x: (CGFloat(cgImage.width) - width)/2, y: (CGFloat(cgImage.height) - height)/2, width: width, height: height)
    }

    func addImageProperties(imageData: Data, properties: NSDictionary?) -> Data? {
        // create an imagesourceref
        if let source = CGImageSourceCreateWithData(imageData as CFData, nil) {
            // this is of type image
            if let uti = CGImageSourceGetType(source) {
                // create a new data object and write the new image into it
                let destinationData = NSMutableData()
                if let destination = CGImageDestinationCreateWithData(destinationData, uti, 1, nil) {
                    // add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
                    CGImageDestinationAddImageFromSource(destination, source, 0, properties)
                    if CGImageDestinationFinalize(destination) == false {
                        return nil
                    }
                    return destinationData as Data
                }
            }
        }
        return nil
    }

    private var photoData : Data? = nil
}

查看模型

<Window.Resources>
            <BooleanToVisibilityConverter x:Key="BoolToVis" />

            <Storyboard x:Key="BlinkingAnimation" Duration="0:0:1" RepeatBehavior="Forever">
                <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Background).(SolidColorBrush.Color)">
                    <DiscreteColorKeyFrame KeyTime="0:0:0" Value="Black" />
                    <DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="Red" />
                </ColorAnimationUsingKeyFrames>
                <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
                    <DiscreteColorKeyFrame KeyTime="0:0:0" Value="Red" />
                    <DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="Black" />
                </ColorAnimationUsingKeyFrames>
            </Storyboard>

            <Style x:Key="BlinkingAnimationStyle" TargetType="{x:Type TextBlock}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=BlinkOn}" Value="true">
                        <DataTrigger.EnterActions>                            
                            <BeginStoryboard x:Name="BlinkingAnimation_BeginStoryboard" Storyboard="{StaticResource BlinkingAnimation}" />                            
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="BlinkingAnimation_BeginStoryboard" />
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=BlinkOn}" Value="false">
                        <DataTrigger.EnterActions>
                            <RemoveStoryboard BeginStoryboardName="BlinkingAnimation_BeginStoryboard" />
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style> 
</Window.Resources>

<Border Visibility="{Binding Path=BlinkOn, Converter={StaticResource BoolToVis}}" BorderThickness="1" BorderBrush="Red" CornerRadius="5" Margin="5">
    <TextBlock x:Name="lblStoryboard" 
               Padding="5"                           
               Width="480"
               Style="{StaticResource BlinkingAnimationStyle}"
               Text="Hey there! I am Blinking!!!" 
               TextWrapping="WrapWithOverflow"
               Visibility="{Binding Path=BlinkOn, Converter={StaticResource BoolToVis}}">
    </TextBlock>
</Border>

1 个答案:

答案 0 :(得分:0)

  1. 您的绑定路径无效。您应该删除RelativeSource={x:Static RelativeSource.Self}
  2. 您需要将Background的{​​{1}}和Foreground属性设置为Label,因为您的SolidColorBrushes试图为其设置动画。

这应该有效:

Storyboard