[英]Storyboard.TargetProperty path contains nonanimatable property 'Text
編輯:
我正在嘗試使用事件觸發器更改 TextBox 的文本,但出現如下運行時錯誤。
System.InvalidOperationException: ''(0)' Storyboard.TargetProperty 路徑包含不可動畫的屬性 '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>
編輯:因為你已經完全重寫了原來的問題,我原來的答案不再有意義,所以我也會重寫它。
問題是在 EventTrigger 中,您只能使用 StoryBoard,而不能從中設置 TextBox 的 Text 屬性。 因此,我認為即使可以通過模板純粹從 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) 時,它只是設置目標 TextBox 的 Text 屬性。 我必須覆蓋 FreezeCore,因為默認情況下它返回了 false,並且在觸發動畫時會導致 InvelidOperationException。
所以這是一個根本沒有動畫的動畫。 :) 我認為這是一個丑陋的解決方案,但如果不使用用戶控件,我無法想出更好的解決方案。
下面是 XAML 標記。 你必須設置動畫的 TargetProperty,雖然最后它沒有被使用——這就是我指定 Tag 的原因。 如果您使用文本框的 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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.