I am attempting to put all my timing logic into an attached behavior. My goals are:
(Using Visual Studio 2010.)
- Simplify my XAML code by replacing many MultiValue triggers,
- Change the background color of each ListViewItem based on a timer and data within the ListViewItem,
- Use a singleton pattern for the timer as I only want one timer for all my ListViewItems.
My problems are:
- How to have the display watch for color changes
- Get the specific ListViewItem instance when the timer event fires ("this" is not allowed), and
- Removing all memory footprints of the static properties and events when the user control holding the ListView and its items is closed.
Problem #3 may be done automatically by WPF and C# (I'm not sure). #1 poses a problem, because if I understand attached properties correctly, the property will only set the background color on initialization so update to the background color will not be made by the simple XAML shown below. Is a Trigger necessary?
How can this be done?
TIA
Here is what I have so far:
XAML
<Style x:Key="listViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="v:ListViewItemBehavior.MyValue" Value="{Binding}"/>
--IS A TRIGGER NEEDED HERE TO UPDATE THE BACKGROUND COLOR, AND IF SO
HOW IS IT BOUND TO THE CLASS OF THE ATTACHED PROPERTY WHICH IS NOT IN THE
VIEW MODEL?
</Style>
Code
// Using singleton pattern to create one time to be shared among all ListViewItem instances.
public static class ListTimer
{
// Reasons for using a DispatcherTimer opposed to a System.Timers.Timer are that the DispatcherTimer runs on the same thread as the
// Dispatcher and a DispatcherPriority can be set on the DispatcherTimer. Timer runs in its own thread.
private static readonly Timer listTimer;
static ListTimer()
{
listTimer = new Timer { AutoReset = true, Enabled = true, Interval = 10 * 1000 }; // Interval in milliseconds
listTimer.Elapsed += listTimer_Elapsed;
}
static void listTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (ListTimerEvent != null)
{
ListTimerEvent(sender, e);
}
}
public static event EventHandler ListTimerEvent;
}
// Static classes can not implement an interface. (Hence : INotifyPropertyChanged can not be used).
public static class ListViewItemBehavior
{
public static string GetMyValue(DependencyObject obj)
{
return (string)obj.GetValue(MyValueProperty);
}
public static void SetMyValue(DependencyObject obj, string value)
{
obj.SetValue(MyValueProperty, value);
}
// Using a DependencyProperty as the backing store for MyValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyValueProperty =
DependencyProperty.RegisterAttached("MyValue", typeof(Object), typeof(ListViewItemBehavior), new UIPropertyMetadata(null, OnMyValueChanged));
static void OnMyValueChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
var item = depObj as ListViewItem;
if (item == null) return;
--EACH INSTANCE HAS ITS OWN VALUE ON VIEW_ENCOUNTERTIME--
View_encountertime vt = item.DataContext as View_encountertime;
ListTimer.ListTimerEvent +=new EventHandler(ListTimer_ListTimerEvent);
}
static void ListTimer_ListTimerEvent(object sender, EventArgs e)
{
Timer timer = sender as Timer;
var y = this.GetValue(MyValueProperty); <-- WRONG! CAN'T USE "THIS"
-- I would put logic to set the background color here for
-- each instance ...if I knew how!
}