I am trying to change the background of a ListViewItem from an attached property. The following code works until the ListViewItem is scrolled out of the displayed ListView. The error is that the timer fires on a ListViewItem that has been disconnected.
{System.Windows.Controls.ListViewItem: {DisconnectedItem}} System.Windows.Controls.ListViewItem
How to test for a disconnected item in visual studio 2010?
TIA
namespace Stargate_V
{
// 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
{
// Hint: create this with "propa" then tab
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 args)
{
var item = depObj as ListViewItem;
if (item == null) return;
// This is unable to pass the instance data: ListTimer.ListTimerEvent +=new EventHandler(ListTimer_ListTimerEvent);
// Use an anonymous method in the OnMyValueChanged to specify the timer event handler. This will give access to the specific
// ListViewItem.
ListTimer.ListTimerEvent += (sender, e) =>
{
Timer timer = sender as Timer;
// The Timer is running on a different thread then the ListViewItem item
item.Dispatcher.Invoke((Action)(() =>
{
--THIS FAILS WHEN ITEM HAS BEEN SCROLLED OUT OF VIEW AND DISCONNECTED ---
View_encountertime vt = item.DataContext as View_encountertime;
item.Background = Brushes.Azure;
// convert checkin time to a datetime.
var b = vt.Checkin;
DateTime z = (DateTime)vt.Tencounter;
// string sdt = DateTime.Now.ToShortDateString() + " " + values[0].ToString();
// DateTime checkin = DateTime.Parse(sdt);
// get current time.
// DateTime now = DateTime.Now;
DateTime now = new DateTime(2015, 2, 13, 11, 30, 5);
TimeSpan ts = now.Subtract(z);
if (ts.CompareTo(WaitingTime.ninetymin) < 1) item.Background = Brushes.Orange; // orange
if (ts.CompareTo(WaitingTime.seventyfivemin) < 1) item.Background = Brushes.Yellow; // yellow
if (ts.CompareTo(WaitingTime.sixtymin) < 1) item.Background = Brushes.Green; // green
if (ts.CompareTo(WaitingTime.fortyfivemin) < 1) item.Background = Brushes.Turquoise; // turquose
if (ts.CompareTo(WaitingTime.thirtymin) < 1) item.Background = Brushes.Blue; // blue
if (ts.CompareTo(WaitingTime.fifteenmin) < 1) item.Background = Brushes.Violet; // violet
}));
};
}
}
// Waiting times
public static class WaitingTime
{
public static TimeSpan fifteenmin;
public static TimeSpan thirtymin;
public static TimeSpan fortyfivemin;
public static TimeSpan sixtymin;
public static TimeSpan seventyfivemin;
public static TimeSpan ninetymin;
static WaitingTime()
{
fifteenmin = new TimeSpan(0, 15, 0);
thirtymin = new TimeSpan(0, 30, 0);
fortyfivemin = new TimeSpan(0, 45, 0);
sixtymin = new TimeSpan(0, 60, 0);
seventyfivemin = new TimeSpan(0, 75, 0);
ninetymin = new TimeSpan(0, 90, 0);
}
} // end class WaitingTime
}
Has nothing to do with the version of Visual Studio. Has to do with the version of .NET. In 4.5 and above, you can use BindingOperations.DisconnectedSource
. Before 4.5, .NET did not expose this member, so you have to do a string compare.