Путь Storyboard.TargetProperty содержит неанимируемое свойство 'Текст - PullRequest
0 голосов
/ 20 февраля 2020

Редактировать:

Я пытаюсь изменить текст TextBox с помощью триггера события, но я получаю ошибку времени выполнения, как показано ниже.

System.InvalidOperationException: '' (0) 'Storyboard.TargetProperty path содержит неанимируемое свойство' Text '.'

Как изменить текст с помощью триггера события в WPF

<Style x:Key="mystyle"
           TargetType="{x:Type TextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">

                    <StackPanel>
                        <ScrollViewer x:Name="PART_ContentHost"
                                      Focusable="false"
                                      HorizontalScrollBarVisibility="Auto"
                                      VerticalScrollBarVisibility="Auto" />

                        <ToggleButton HorizontalAlignment="Right"
                                VerticalAlignment="Top"
                                Content="search"
                                Name="searchButton">
                            <ToggleButton.Triggers>
                                <EventTrigger RoutedEvent="Button.Click">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <StringAnimationUsingKeyFrames Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorType=TextBox,AncestorLevel=1}}"
                                                                           Storyboard.TargetProperty="(TextBox.Text)">
                                                <DiscreteStringKeyFrame KeyTime="00:00:00"
                                                                        Value="texttwo" />
                                            </StringAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </ToggleButton.Triggers>
                        </ToggleButton>
                    </StackPanel>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

1 Ответ

1 голос
/ 20 февраля 2020

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

Проблема в том, что в EventTrigger вы можете использовать только StoryBoard , и вы не можете установить свойство Text для TextBox из него. Поэтому я думаю, что даже если это может быть достигнуто исключительно из WPF с шаблоном, решение будет настолько сложным и уродливым, что оно того не стоит, поэтому я бы предложил создать пользовательский элемент управления. Если мы сделаем шаг назад, какова ваша цель с этим настраиваемым TextBox?

Edit2: Наконец, я мог бы сделать это с помощью пользовательского класса анимации, но я все еще думаю, что реализация этой функциональности с помощью пользовательского элемента управления - это хорошо решение. Это пользовательский класс анимации (для простоты я поместил его в «локальное» пространство имен):

    public class TextBoxStringAnimation : StringAnimationBase {
        public static readonly DependencyProperty TextBoxToChangeProperty = DependencyProperty.Register(nameof(TextBoxToChange), typeof(TextBox), typeof(TextBoxStringAnimation));
        public TextBox TextBoxToChange {
            get => (TextBox)this.GetValue(TextBoxToChangeProperty);
            set => this.SetValue(TextBoxToChangeProperty, value);
        }
        public static readonly DependencyProperty NewTextProperty = DependencyProperty.Register(nameof(NewText), typeof(string), typeof(TextBoxStringAnimation));
        public string NewText {
            get => (string)this.GetValue(NewTextProperty);
            set => this.SetValue(NewTextProperty, value);
        }
        protected override Freezable CreateInstanceCore() => new TextBoxStringAnimation();
        protected override string GetCurrentValueCore(string defaultOriginValue, string defaultDestinationValue, AnimationClock animationClock) {
            TextBoxToChange.Text = NewText;
            return defaultDestinationValue;
        }
        protected override bool FreezeCore(bool isChecking) {
            return true;
        }
    }

Это наследуется от StringAnimationBase, и вы можете установить значения TextBox и NewText напрямую. Я реализовал оба свойства как зависимости, так что вы можете связать их.

При получении текущего значения (GetCurrentValueCore) он просто устанавливает свойство Text целевого TextBox. Мне пришлось переопределить FreezeCore, потому что по умолчанию он возвращает false, и это вызывает InvelidOperationException, когда анимация запускается.

Так что это анимация, которая вообще не анимируется. :) Я считаю это уродливым решением, но без использования пользовательского элемента управления я не смог бы найти лучшего решения.

Ниже приведена разметка XAML. Вы должны установить TargetProperty анимации, хотя в конце она не используется - вот почему я указал тег. Если вы используете свойство Tag текстового поля, проверьте, сбрасывает ли анимация его или нет.

        <Style x:Key="mystyle" TargetType="{x:Type TextBox}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <StackPanel>
                            <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" />

                            <ToggleButton HorizontalAlignment="Right" VerticalAlignment="Top" Content="search" Name="searchButton">
                                <ToggleButton.Triggers>
                                    <EventTrigger RoutedEvent="Button.Click">
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <local:TextBoxStringAnimation TextBoxToChange="{Binding RelativeSource={RelativeSource AncestorType=TextBox,AncestorLevel=1}}"
                                                                              NewText="texttwo" Storyboard.TargetProperty="(TextBox.Tag)"/>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                </ToggleButton.Triggers>
                            </ToggleButton>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...