現象
コード
仮説
通常、BInding が Backgroundである場合、Brush を指定する。所が storyboardでは animateするpropertyに Backgroundと記載するだけでは動作せず、Background.Colorと指定する必要がある。これはBackgroundの中のColorプロパティだけを操作するという意味になる。
このような仕組みとすれば、恐らくwpfでは BackgroundをBindingした場合、Backgroundへのアクセスでえらるobject型ではBrushではなく、そこで Bindingによってラッピングされた何かが戻ってきていると考える。
とはいえ、この辺りの仕組みはよく分からず、何を指定すれば解決できるかは不明。たぶん、どっかのstack overflowには答えがありそう。
回避策
BackgroundをBindingしない事で Animationを動かす。
Bindingにより実現したかった事は、色を変えるタイミングに対して、ViewModelのコマンドを呼び出す。パラメータのExecutedRoutedEventArgs.OriginalSourceにはボタンインスタンスがあるので色を変更できる。
または、xamlのイベントをコードビハインドにし、そこから ViewModelから変えたい色情報を取り出す。
System.InvalidOperationException:
'Cannot animate 'Background.Color' on an immutable object instance.'
コード
<Button Content="ボタン2" Background="{Binding background}" x:Name="LPB2" Width="200" Height="120"> <Button.Triggers> <-- ButtonDown で animation を開始する --> <EventTrigger RoutedEvent="PreviewMouseLeftButtonDown"> <BeginStoryboard> <Storyboard TargetName="LPB2"> <-- 500msで背景を白色にする。ここで問題なのが TargetProperty。 --> <ColorAnimation Storyboard.TargetProperty="Background.Color" To="White" Duration="0:0:0.500" /> </Storyboard> </BeginStoryboard> </EventTrigger> <-- ButtonUp で元の色に戻す --> <EventTrigger RoutedEvent="PreviewMouseLeftButtonUp"> <BeginStoryboard> <Storyboard TargetName="LPB2"> <ColorAnimation Storyboard.TargetProperty="Background.Color" To="SkyBlue" Duration="0" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button>
仮説
通常、BInding が Backgroundである場合、Brush を指定する。所が storyboardでは animateするpropertyに Backgroundと記載するだけでは動作せず、Background.Colorと指定する必要がある。これはBackgroundの中のColorプロパティだけを操作するという意味になる。
このような仕組みとすれば、恐らくwpfでは BackgroundをBindingした場合、Backgroundへのアクセスでえらるobject型ではBrushではなく、そこで Bindingによってラッピングされた何かが戻ってきていると考える。
とはいえ、この辺りの仕組みはよく分からず、何を指定すれば解決できるかは不明。たぶん、どっかのstack overflowには答えがありそう。
回避策
BackgroundをBindingしない事で Animationを動かす。
Bindingにより実現したかった事は、色を変えるタイミングに対して、ViewModelのコマンドを呼び出す。パラメータのExecutedRoutedEventArgs.OriginalSourceにはボタンインスタンスがあるので色を変更できる。
または、xamlのイベントをコードビハインドにし、そこから ViewModelから変えたい色情報を取り出す。
public void Command ( object sender, ExecutedRoutedEventArgs e )
{
var btn = e.OriginalSource as Button;
var b = btn.Background;
if( b == Brushes.LightSeaGreen )
{
b = Brushes.CornflowerBlue;
}
else
{
b = Brushes.LightSeaGreen;
}
btn.Background = b;
}