は、このコードを考えてみましょう:XAMLから要素リソース内のストーリーボードにアクセスするにはどうすればよいですか?
<UserControl x:Class="MyApp.MyControl"
...
xmlns:local="clr-namespace:MyApp"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<UserControl.Template>
<ControlTemplate>
<ControlTemplate.Resources>
<Storyboard x:Key="MyStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="brdBase">
<SplineColorKeyFrame KeyTime="0:0:1" Value="Red"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border x:Name="brdBase" BorderThickness="1" BorderBrush="Cyan" Background="Black">
...
</Border>
<ControlTemplate.Triggers>
<Trigger SourceName="brdBase" Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MyStory}"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</UserControl.Template>
</UserControl>
上記のコードは問題なく動作します。
エラーになり<Storyboard x:Key="MyStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="brdBase">
<SplineColorKeyFrame KeyTime="0:0:1" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyControl}}, Path=SpecialColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
:
はこのストーリーボードのタイムラインツリーを凍結することはできませんが、今、私はそうのように、このユーザー・コントロールの(SpecialColor
命名)DPへMyStory
のバインドキーフレーム値をしたいですスレッド間で使用する。
これはコードの背後で行うことができます。しかし、どうすればXAMLでそれを行うことができますか?コードビハインド
ソリューション支援:
►ステップ1:はbrdBase
リソースへMyStory
ストーリーボードを置きます。
<UserControl.Template>
<ControlTemplate>
<Border x:Name="brdBase" BorderThickness="1" BorderBrush="Cyan" Background="Black">
<Border.Resources>
<Storyboard x:Key="MyStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="brdBase">
<SplineColorKeyFrame KeyTime="0:0:1" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyControl}}, Path=SpecialColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Border.Resources>
...
</Border>
<ControlTemplate.Triggers>
<Trigger SourceName="brdBase" Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MyStory}"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</UserControl.Template>
エラー:は 'あるmyStory' という名前のリソースを見つけることができません。リソース名は大文字と小文字を区別します
►ステップ2:IsMouseOver
性質上Trigger
を排除し、背後にあるコードからMyStory
を開始します。
<UserControl.Template>
<ControlTemplate>
<Border x:Name="brdBase" BorderThickness="1" BorderBrush="Cyan" Background="Black" MouseEnter="brdBase_MouseEnter">
<Border.Resources>
<Storyboard x:Key="MyStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="brdBase">
<SplineColorKeyFrame KeyTime="0:0:1" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyControl}}, Path=SpecialColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Border.Resources>
</Border>
</ControlTemplate>
</UserControl.Template>
C#のコードビハインド:
private void brdBase_MouseEnter(object sender, MouseEventArgs e)
{
Border grdRoot = (Border)this.Template.FindName("brdBase", this);
Storyboard story = grdRoot.Resources["MyStory"] as Storyboard;
story.Begin(this, this.Template);
}
►ステップ3:溶液がすでに行われているが、それは最初の時間では動作しません。幸いにも、この問題の回避策があります。 ControlTemplate
をStyle
に入れるだけで十分です。
は(私はEventTrigger
以外のTrigger
の種類を必要とControlTemplate
とUserControl
要素をラップする必要があります。)
を更新:
ObjectDataProvider
の使用についての考えは失敗しました。
- たObjectDataProviderリソースは、ストーリーボードを提供するために使用することはできません!エラーレポート:例外をスローした設定するプロパティ 'System.Windows.Media.Animation.BeginStoryboard.Storyboard':
- XamlParseException。
- InnerException: 'System.Windows.Data。ObjectDataProvider 'はプロパティ' Storyboard 'の有効な値ではありません。
- AssociatedControl DPは常にnullです。ここで
コードです:
<UserControl.Template>
<ControlTemplate>
<ControlTemplate.Resources>
<local:StoryboardFinder x:Key="StoryboardFinder1" AssociatedControl="{Binding ElementName=brdBase}"/>
<ObjectDataProvider x:Key="dataProvider" ObjectInstance="{StaticResource StoryboardFinder1}" MethodName="Finder">
<ObjectDataProvider.MethodParameters>
<sys:String>MyStory</sys:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ControlTemplate.Resources>
<Border x:Name="brdBase" BorderThickness="1" BorderBrush="Cyan" Background="Black">
<Border.Resources>
<Storyboard x:Key="MyStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="brdBase">
<SplineColorKeyFrame KeyTime="0:0:1" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyControl}}, Path=SpecialColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Border.Resources>
...
</Border>
<ControlTemplate.Triggers>
<Trigger SourceName="brdBase" Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource dataProvider}"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</UserControl.Template>
StoryboardFinderクラス:
public class StoryboardFinder : DependencyObject
{
#region ________________________________________ AssociatedControl
public Control AssociatedControl
{
get { return (Control)GetValue(AssociatedControlProperty); }
set { SetValue(AssociatedControlProperty, value); }
}
public static readonly DependencyProperty AssociatedControlProperty =
DependencyProperty.Register("AssociatedControl",
typeof(Control),
typeof(StoryboardFinder),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None));
#endregion
public Storyboard Finder(string resourceName)
{
//
// Associated control is always null :(
//
return new Storyboard();
}
}
それはいいです、それは問題なく動作するはずです。私が見ることができる唯一のことは、ストーリーボードのタイムラインをもう凍結しないで、複数のスレッドを使用していないことを意味するため、効率が低下する可能性があるということです。 –
あなたは正しいです。私は 'TriggerAction'の' Invoke'メソッドを呼び出す方法を探しています。このようにして、必要なものはすべて内部的に行う必要があります。何について考えていますか? (私は 'このスニペットを使用できませんでした 'とマークしました) – Mimi
別のビューでは、実際には、Begin()は自動的にフリーズします。なぜXamlは正しく動作しないのですか?とにかく、内部のものにアクセスしようとしているのはなぜですか? –