これはおそらくあなたが望むほど単純ではありませんが、あなたが必要とするもののために機能します。このコードはすべて私のテストハーネスのメインウィンドウにあるため、特定の状況に合わせて変更する必要がある場合があります。考え方は同じです。
最初に行う必要があるのは、コレクションが変更されたときにイベントを取得するように設定することです。観察可能なコレクションを使用します。これは、バインドしている場合は、それを使用していると想定するためです。
ObservableCollection<String> m_NotificationList;
// Propertized for binding purposes
public ObservableCollection<String> NotificationList
{
get
{
return m_NotificationList;
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
m_NotificationList = new ObservableCollection<string>() { "hey", "ho", "lets", "go" };
m_NotificationList.CollectionChanged += CollectionChangeCallback;
}
次のステップは、それ自体をフラッシュするときにウィンドウに送信できるルーティングされたイベントを定義することです。上記のように、メインウィンドウのクラス定義でこれを行います。
public static readonly RoutedEvent FlashEvent =
EventManager.RegisterRoutedEvent("Flash",
RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(MainWindow));
public event RoutedEventHandler Flash
{
add { AddHandler(FlashEvent, value); }
remove { RemoveHandler(FlashEvent, value); }
}
次に、コレクションが更新されたときのコールバックを、メインウィンドウのクラス定義で定義する必要があります。
void CollectionChangeCallback(object sender, EventArgs e)
{
// Don't fire if we don't want to flash
if (m_NotificationList.Count > 0)
window.RaiseEvent(new RoutedEventArgs(FlashEvent));
}
次に、XAMLに移動し、MainWindowにトリガーを追加します。このトリガーは、作成したばかりのルーティングされたイベントを処理し、実行するアニメーションを実行します。
<Window.Triggers>
<EventTrigger RoutedEvent="local:MainWindow.Flash" >
<BeginStoryboard>
<Storyboard>
<ColorAnimation AutoReverse="True"
Duration="0:0:1"
FillBehavior="Stop"
From="White"
Storyboard.TargetName="window"
Storyboard.TargetProperty="Background.Color"
To="Red" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
これは、私のテストハーネスで要求されたとおりに機能します。それは少し厄介ですが、私はそれを行うためのより良い方法を見つけることができませんでした。わかりやすくするために、コードビハインドを含むXAMLもここに含めます。これは、MenuItemと、コレクションに文字列を追加するボタンがある空のウィンドウです。あなたはフラッシュとそれを実現するためにイベントが一緒になる方法を見ることができます。
XAML:
<Window x:Class="WPFTestbed.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFTestbed"
x:Name="window"
Title="MainWindow"
Width="525"
Height="350">
<Window.Triggers>
<EventTrigger RoutedEvent="local:MainWindow.Flash" >
<BeginStoryboard>
<Storyboard>
<ColorAnimation AutoReverse="True"
Duration="0:0:1"
FillBehavior="Stop"
From="White"
Storyboard.TargetName="window"
Storyboard.TargetProperty="Background.Color"
To="Red" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<StackPanel>
<MenuItem x:Name="menu"
Header="{Binding NotificationList.Count}"
HeaderStringFormat="Notifications ({0})"
ItemsSource="{Binding NotificationList}">
</MenuItem>
<Button Click="Button_Click"
Content="Hi" />
</StackPanel>
</Window>
コードビハインド(-スペースを含む):
namespace WPFTestbed
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public static readonly RoutedEvent FlashEvent =
EventManager.RegisterRoutedEvent("Flash",
RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(MainWindow));
public event RoutedEventHandler Flash
{
add { AddHandler(FlashEvent, value); }
remove { RemoveHandler(FlashEvent, value); }
}
ObservableCollection<String> m_NotificationList;
public ObservableCollection<String> NotificationList
{
get
{
return m_NotificationList;
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
m_NotificationList = new ObservableCollection<string>() { "hey", "ho", "lets", "go" };
m_NotificationList.CollectionChanged += CollectionChangeCallback;
}
void CollectionChangeCallback(object sender, EventArgs e)
{
if (m_NotificationList.Count > 0)
window.RaiseEvent(new RoutedEventArgs(FlashEvent));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
m_NotificationList.Add("Another");
}
}
}