XAML 无法在不可变对象示例上设置“(0).(1)”的动画

xxhby3vn  于 11个月前  发布在  其他
关注(0)|答案(4)|浏览(128)

我有一个用户控件,我想在特定的时间动画。我将其中两个用户控件添加到一个窗口。我使用该窗口中的一个按钮来启动动画。其中一个用户控件工作正常。第二个用户控件给了我一个不可变对象示例错误,无法动画'(0).(1)'。我根本不明白!为什么一个可以工作,而另一个不行?我正在阅读关于需要一个转换器-但我不能得到它的工作在所有.我离开了代码在这里,以防万一我确实需要它.谢谢你的任何帮助,你可以给予我在这方面.我是新的WPF,所以我可能会做一些愚蠢的东西在这里-请原谅我.这是我的代码为用户控制:

<UserControl x:Class="colorCompButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:Local="clr-namespace:UserControlTests"
         xmlns:custom="clr-namespace:UserControlTests"

         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" Height="179" Width="317">
<UserControl.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    <Storyboard x:Key="sb2" RepeatBehavior="Forever" x:Name="thisone">

        <ColorAnimation Storyboard.TargetName="badge1" 
      Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" From="Red" To="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=BadgeColor}" 
      Duration="0:0:1" />

    </Storyboard>
</UserControl.Resources>

<Grid Margin="0,0,10,10">

    <Rectangle x:Name="rect"   HorizontalAlignment="Left" Height="135"  VerticalAlignment="Top" Width="259" x:FieldModifier="public"  Fill ="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=RectColor}"/>
    <Image x:Name="image" Height="87" Margin="10,10,63,0" VerticalAlignment="Top" x:FieldModifier="public" Source ="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ImageSource}"/>

    <TextBlock x:Name="textBlock" Margin="0,102,10,38" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=TxtBoxValue}" Background="Transparent" Foreground="White" FontSize="20" Padding="3"/>

    <Grid Margin="222,81,0,0" x:Name="NumberIMG" Height="78" VerticalAlignment="Top" HorizontalAlignment="Left" Width="85" Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=BadgeVisibile}" >
        <Border BorderBrush="Maroon" BorderThickness="1" CornerRadius="120" Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=BadgeColor}" HorizontalAlignment="Left" Height="76"  VerticalAlignment="Top" Width="76" x:Name="badge1" x:FieldModifier="public"></Border>
        <Border BorderBrush="black" Margin="2,2,0,0" BorderThickness="3" Opacity=".5" CornerRadius="120"  HorizontalAlignment="Left" Height="74"  VerticalAlignment="Top" Width="74"></Border>
        <Border BorderBrush="White" BorderThickness="3" CornerRadius="120"  HorizontalAlignment="Left" Height="78" VerticalAlignment="Top" Width="78">
            <Label x:Name="resCount" Content="46" FontSize="25"  Foreground="White"  HorizontalContentAlignment="center" VerticalContentAlignment="center" Margin="0,0,-3,-3"/>
        </Border>
    </Grid>

</Grid>

字符串
这个控件背后的代码是:

Imports System.Windows.Media.Animation

Public Class colorCompButton
Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

End Sub
'Public Shared Sub SetImage(obj As DependencyObject, value As ImageSource)
'    obj.SetValue(ImageProperty, value)
'End Sub
'Public Shared Function GetImage(obj As DependencyObject) As ImageSource
'    Return DirectCast(obj.GetValue(ImageProperty), ImageSource)
'End Function

Shared Sub New()
    'register attached dependency property

    Dim metadata = New FrameworkPropertyMetadata(DirectCast(Nothing, ImageSource))
    'ImageProperty = DependencyProperty.RegisterAttached("Image", GetType(ImageSource), GetType(colorCompButton), metadata)
End Sub

Public Shared ReadOnly BadgeVisibileProperty As DependencyProperty = DependencyProperty.Register("BadgeVisibile", GetType(Visibility), GetType(colorCompButton), New PropertyMetadata(Visibility.Visible))

Public Property BadgeVisibile() As Visibility
    Get
        Return DirectCast(GetValue(BadgeVisibileProperty), Visibility)
    End Get
    Set(value As Visibility)
        SetValue(BadgeVisibileProperty, value)
    End Set
End Property

Public Shared ReadOnly BadgeColorProperty As DependencyProperty = DependencyProperty.Register("BadgeColor", GetType(Brush), GetType(colorCompButton), New PropertyMetadata(New SolidColorBrush(Colors.DarkGray)))
Public Property BadgeColor() As SolidColorBrush
    Get
        Return DirectCast(GetValue(BadgeColorProperty), SolidColorBrush)
    End Get
    Set(value As SolidColorBrush)
        SetValue(BadgeColorProperty, value)
    End Set
End Property

Public Shared ReadOnly buttonColorProperty As DependencyProperty = DependencyProperty.Register("buttonColor", GetType(Brush), GetType(colorCompButton), New PropertyMetadata(New SolidColorBrush(Colors.DarkGray)))
Public Property buttonColor() As SolidColorBrush
    Get
        Return DirectCast(GetValue(buttonColorProperty), SolidColorBrush)
    End Get
    Set(value As SolidColorBrush)
        SetValue(buttonColorProperty, value)
    End Set
End Property

Public Shared ReadOnly ImageSourceProperty As DependencyProperty = DependencyProperty.Register("ImageSource", GetType(BitmapSource), GetType(colorCompButton))
Public Property ImageSource() As ImageSource
    Get
        Return DirectCast(GetValue(ImageSourceProperty), ImageSource)
    End Get
    Set(value As ImageSource)
        SetValue(ImageSourceProperty, value)
    End Set
End Property

Public Shared ReadOnly RectColorProperty As DependencyProperty = DependencyProperty.Register("RectColor", GetType(Brush), GetType(colorCompButton), New PropertyMetadata(New SolidColorBrush(Colors.DarkGray)))
Public Property RectColor() As SolidColorBrush
    Get
        Return DirectCast(GetValue(RectColorProperty), SolidColorBrush)
    End Get
    Set(value As SolidColorBrush)
        SetValue(RectColorProperty, value)
    End Set
End Property

Public Shared TxtBoxValueProperty As DependencyProperty = DependencyProperty.Register("txtBoxValue", GetType([String]), GetType(colorCompButton))
Public Property TxtBoxValue() As [String]
    Get
        Return DirectCast(GetValue(TxtBoxValueProperty), [String])
    End Get
    Set(value As [String])
        SetValue(TxtBoxValueProperty, value)
    End Set
End Property
Public Sub StartLeafUp()
    Dim sb As Storyboard = TryCast(Me.Resources("sb2"), Storyboard)
    sb.Begin()
End Sub

Public Sub StartLeafDown()
    Dim sb As Storyboard = TryCast(Me.Resources("sb2"), Storyboard)
    sb.Stop()
End Sub
End Class
Friend Class MyCloneConverter
Implements IValueConverter

Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
    If TypeOf value Is Freezable Then
        value = TryCast(value, Freezable).Clone()
    End If

    Return value
End Function

Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
    Throw New NotSupportedException()
End Function
End Class


主窗口和后面的代码:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UserControlTests" x:Class="MainWindow"
Title="MainWindow" Height="437" Width="1057">

<Grid>

    <local:colorCompButton x:Name="color" Margin="201,62,0,0"  VerticalAlignment="Top" HorizontalAlignment="Left" BadgeColor="#FF833E1D" buttonColor="Sienna" RectColor="Sienna" ImageSource="pack://siteoforigin:,,,/images/deviation.png" TxtBoxValue="I WORK"/>
    <Button x:Name="button" Content="WORKS FINE" HorizontalAlignment="Left" Margin="336,262,0,0" VerticalAlignment="Top" Width="160" Height="53"/>

    <Button x:Name="button1" Content="DOES NOT WORK!!" HorizontalAlignment="Left" Margin="534,262,0,0" VerticalAlignment="Top" Width="144" Height="53"/>
    <local:colorCompButton HorizontalAlignment="Left" Margin="534,62,0,0" VerticalAlignment="Top" BadgeColor="Indigo" RectColor="IndianRed" ImageSource="pack://siteoforigin:,,,/images/deviation.png" TxtBoxValue="I WON'T WORK" x:Name="res"/>
    <Label x:Name="label" Content="EXACT SAME CONTROLS.  WHY WILL THIS NOT WORK??" HorizontalAlignment="Left" Margin="375,365,0,0" VerticalAlignment="Top"/>

</Grid>

Imports System.Windows.Media.Animation

Class MainWindow

Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
    color.StartLeafUp()

End Sub

Private Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click
    res.StartLeafUp()

End Sub
End Class

i5desfxk

i5desfxk1#

这可能不是最好的答案,但我自己解决了这个问题,添加了另一个边框,将其背景设置为透明,并将其动画化,而不是第一个边框。这似乎更像是一个黑客而不是解决方案,但它确实有效。我仍然愿意听到一个真实的解决方案-如果有人有的话。

ecr0jaav

ecr0jaav2#

我这样做的原因是:

Background="{Binding ElementName=ToggleButton, Path=Background}"

字符串
而不是这样:

Background="{TemplateBinding Background}"


我在一个控件模板中设置了动画。
看来你也犯了同样的错误:-)

6za6bjd0

6za6bjd03#

我有同样的错误/问题,而试图动画文本块前景属性。
一种解决方法是创建Color类型DependencyProperty并将其设置为颜色动画的目标。然后,例如,将TextBlock Foreground属性绑定到宿主UserControl(或Window)的DependencyProperty,并使用转换器从Color创建Brush。
下面是一个我命名为SpectrumTextBlock的 Flink TextBlock的示例,它在加载控件时启动动画:
XAML:

<UserControl x:Class="Common.SpectrumTextBlock"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:Common"
         mc:Ignorable="d"
         x:Name="spectrumTextBlock">

<UserControl.Resources>

    <local:ColorToBrushConverter x:Key="colorToBrushConverter"/>

    <Storyboard x:Key="spectrumStoryboard" RepeatBehavior="Forever">
        <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(EffectColor)" Storyboard.TargetName="spectrumTextBlock">
            <EasingColorKeyFrame KeyTime="0" Value="Black"/>
            <EasingColorKeyFrame KeyTime="0:0:0.1" Value="Red"/>
            <EasingColorKeyFrame KeyTime="0:0:0.2" Value="Orange"/>
            <EasingColorKeyFrame KeyTime="0:0:0.3" Value="Yellow"/>
            <EasingColorKeyFrame KeyTime="0:0:0.4" Value="Green"/>
            <EasingColorKeyFrame KeyTime="0:0:0.5" Value="Cyan"/>
            <EasingColorKeyFrame KeyTime="0:0:0.6" Value="Blue"/>
            <EasingColorKeyFrame KeyTime="0:0:0.7" Value="Violet"/>
        </ColorAnimationUsingKeyFrames>
    </Storyboard>

</UserControl.Resources>

<TextBlock Text="TEST TEXT" Foreground="{Binding ElementName=spectrumTextBlock, Path=EffectColor, Converter={StaticResource colorToBrushConverter}}"/>

字符串
以及包含转换器的该控件的CS文件:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Common
{
public partial class SpectrumTextBlock : UserControl
{
    private Storyboard _effestStoryboard;

    public Color EffectColor
    {
        get { return (Color)GetValue(EffectColorProperty); }
        set { SetValue(EffectColorProperty, value); }
    }

    public static readonly DependencyProperty EffectColorProperty =
        DependencyProperty.Register("EffectColor", typeof(Color), typeof(SpectrumTextBlock), new PropertyMetadata(SystemColors.ControlTextColor));

    public SpectrumTextBlock()
    {
        InitializeComponent();
        this.Loaded += SpectrumTextBlock_Loaded;
    }

    private void SpectrumTextBlock_Loaded(object sender, RoutedEventArgs e)
    {
        _effestStoryboard = (Storyboard)FindResource("spectrumStoryboard");
        _effestStoryboard.Begin();
    }
}

internal class ColorToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return new SolidColorBrush((Color)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


}
另一种解决方法是使用0 px大小(不可见)的Rectangle并对Fill属性进行动画处理,然后将TextBlock Foreground属性绑定到Rectangle的Fill属性。但第一种DependencyProperty解决方法看起来不那么“笨拙”。

2izufjch

2izufjch4#

任何一个面对这个问题的人:
无法在不可变对象示例上设置“(0).(1)”的动画
添加[VisualState x:Name="Normal"]解决了这个问题。
下面的代码是一个例子:
XAML:

<Style TargetType="RadioButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="RadioButton">
                <Border x:Name="borderIn" 
                        CornerRadius="0">
                    <Label>
                        <ContentPresenter/>
                    </Label>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="borderIn" 
                                                    Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                    FillBehavior="HoldEnd" Duration="0"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimation To="LightBlue" Storyboard.TargetName="borderIn" 
                                                    Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                    FillBehavior="HoldEnd" Duration="0"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="CheckStates">
                            <VisualState x:Name="Unchecked">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="borderIn" 
                                                    Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                    FillBehavior="HoldEnd" Duration="0"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Checked">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="borderIn" 
                                                    Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                    FillBehavior="HoldEnd" Duration="0"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="Background" TargetName="borderIn" Value="LightCyan" />
                    </Trigger>
                    <Trigger Property="IsChecked" Value="false">
                        <Setter TargetName="borderIn" Property="Background" Value="Transparent"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

字符串
希望这个解决方案能帮助那些面临同样问题的人

相关问题