昔書いた記事にコメントがついたので改めてやってみました。
最近はGitHubがあるのでコードを共有するのが楽でいいですね。
こんなクラスを用意してやります。BehaviorをCloneして追加してやる感じです。Cloneして渡さないと同じBehaviorのインスタンスは、複数クラスにアタッチできないのがポイントです。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Interactivity; namespace StyleBehaviorSampleApp { public class StyleBehaviorCollection : FreezableCollection<Behavior> { public static readonly DependencyProperty StyleBehaviorsProperty = DependencyProperty.RegisterAttached( "StyleBehaviors", typeof(StyleBehaviorCollection), typeof(StyleBehaviorCollection), new PropertyMetadata((sender, e) => { if (e.OldValue == e.NewValue) { return; } var value = e.NewValue as StyleBehaviorCollection; if (value == null) { return; } var behaviors = Interaction.GetBehaviors(sender); behaviors.Clear(); foreach (var b in value.Select(x => (Behavior)x.Clone())) { behaviors.Add(b); } })); public static StyleBehaviorCollection GetStyleBehaviors(DependencyObject obj) { return (StyleBehaviorCollection)obj.GetValue(StyleBehaviorsProperty); } public static void SetStyleBehaviors(DependencyObject obj, StyleBehaviorCollection value) { obj.SetValue(StyleBehaviorsProperty, value); } protected override Freezable CreateInstanceCore() { return new StyleBehaviorCollection(); } } }
あとは、適当なBehaviorを作ってこんな感じで使います。
<Window x:Class="StyleBehaviorSampleApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:StyleBehaviorSampleApp" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <Style x:Key="ButtonAlertStyle" TargetType="{x:Type Button}"> <Setter Property="local:StyleBehaviorCollection.StyleBehaviors"> <Setter.Value> <local:StyleBehaviorCollection> <local:AlertBehavior Message="Hello world" /> </local:StyleBehaviorCollection> </Setter.Value> </Setter> </Style> </Window.Resources> <StackPanel> <Button Content="Alert1" Style="{StaticResource ButtonAlertStyle}" /> <Button Content="Alert2" Style="{StaticResource ButtonAlertStyle}" /> <Button Content="Alert3" Style="{StaticResource ButtonAlertStyle}" /> </StackPanel> </Window>
ソースコード全体は以下からどうぞ。