// Performs custom drop logic for the top ListView.
        void dragMgr_ProcessDrop(object sender, ProcessDropEventArgs <Task> e)
        {
            // This shows how to customize the behavior of a drop.
            // Here we perform a swap, instead of just moving the dropped item.

            if (!Program.options.interface_databank_swap)
            {
                MessageBox.Show("*** ERROR: Databank swapping not allowed, since 'OPTION interface databank swap = no'");
                return;
            }

            string text = "";

            int higherIdx = Math.Max(e.OldIndex, e.NewIndex);
            int lowerIdx  = Math.Min(e.OldIndex, e.NewIndex);

            Task t_from = list[e.OldIndex];
            Task t_to   = list[e.NewIndex];

            string aliasFromOld = t_from.AliasName;
            string aliasToOld   = t_to.AliasName;

            string s = null;

            if (lowerIdx < 0)
            {
                // The item came from the lower ListView
                // so just insert it.
                e.ItemsSource.Insert(higherIdx, e.DataItem);
            }
            else
            {
                // null values will cause an error when calling Move.
                // It looks like a bug in ObservableCollection to me.
                if (e.ItemsSource[lowerIdx] == null ||
                    e.ItemsSource[higherIdx] == null)
                {
                    Program.ShowPeriodInStatusField("");
                    return;
                }

                // The item came from the ListView into which
                // it was dropped, so swap it with the item
                // at the target index.
                e.ItemsSource.Move(lowerIdx, higherIdx);
                e.ItemsSource.Move(higherIdx - 1, lowerIdx);

                Databank lower  = Program.databanks.storage[lowerIdx];
                Databank higher = Program.databanks.storage[higherIdx];
                Program.databanks.storage[lowerIdx]  = higher;
                Program.databanks.storage[higherIdx] = lower;
                //remember that higher is at lowerIdx and vice versa!
                if ((lowerIdx == 0 || lowerIdx == 1) && !(G.equal(higher.aliasName, Globals.Work) || G.equal(higher.aliasName, Globals.Ref)))
                {
                    if (!higher.protect)
                    {
                        higher.protect = true;
                        s += "Note that the databank '" + higher.aliasName + "' has been set non-editable. ";
                        list[lowerIdx].Prot = Globals.protectSymbol;
                    }
                }
                //remember that higher is at lowerIdx and vice versa!
                if ((higherIdx == 0 || higherIdx == 1) && !(G.equal(lower.aliasName, Globals.Work) || G.equal(lower.aliasName, Globals.Ref)))
                {
                    if (!lower.protect)
                    {
                        lower.protect        = true;
                        s                   += "Note that the databank '" + lower.aliasName + "' has been set non-editable. ";
                        list[higherIdx].Prot = Globals.protectSymbol;
                    }
                }

                int counter = 0;
                foreach (var x in e.ItemsSource)
                {
                    counter++;
                    x.Number = counter.ToString();
                    if (x.Number == "2")
                    {
                        x.LineColor = "Black";                   //these numbers are 1-based and are strings!
                    }
                    else
                    {
                        x.LineColor = "LightGray";
                    }
                }
            }

            // Set this to 'Move' so that the OnListViewDrop knows to
            // remove the item from the other ListView.
            e.Effects = DragDropEffects.Move;
            //unswap.IsEnabled = Program.AreDatabanksSwapped();
            //unswap.IsEnabled = true;  //fixme

            yellow.Text = "Databanks were swapped. " + s;
            Program.ShowPeriodInStatusField("");
        }
        void listView_Drop(object sender, DragEventArgs e)
        {
            if (this.ItemUnderDragCursor != null)
            {
                this.ItemUnderDragCursor = null;
            }

            e.Effects = DragDropEffects.None;

            if (!e.Data.GetDataPresent(typeof(ItemType)))
            {
                return;
            }

            // Get the data object which was dropped.
            ItemType data = e.Data.GetData(typeof(ItemType)) as ItemType;

            if (data == null)
            {
                return;
            }

            // Get the ObservableCollection<ItemType> which contains the dropped data object.
            ObservableCollection <ItemType> itemsSource = this.listView.ItemsSource as ObservableCollection <ItemType>;

            if (itemsSource == null)
            {
                throw new Exception(
                          "A ListView managed by ListViewDragManager must have its ItemsSource set to an ObservableCollection<ItemType>.");
            }

            int oldIndex = itemsSource.IndexOf(data);
            int newIndex = this.IndexUnderDragCursor;

            if (newIndex < 0)
            {
                // The drag started somewhere else, and our ListView is empty
                // so make the new item the first in the list.
                if (itemsSource.Count == 0)
                {
                    newIndex = 0;
                }

                // The drag started somewhere else, but our ListView has items
                // so make the new item the last in the list.
                else if (oldIndex < 0)
                {
                    newIndex = itemsSource.Count;
                }

                // The user is trying to drop an item from our ListView into
                // our ListView, but the mouse is not over an item, so don't
                // let them drop it.
                else
                {
                    return;
                }
            }

            // Dropping an item back onto itself is not considered an actual 'drop'.
            if (oldIndex == newIndex)
            {
                return;
            }

            if (this.ProcessDrop != null)
            {
                // Let the client code process the drop.
                ProcessDropEventArgs <ItemType> args = new ProcessDropEventArgs <ItemType>(itemsSource, data, oldIndex, newIndex, e.AllowedEffects);
                this.ProcessDrop(this, args);
                e.Effects = args.Effects;
            }
            else
            {
                // Move the dragged data object from it's original index to the
                // new index (according to where the mouse cursor is).  If it was
                // not previously in the ListBox, then insert the item.
                if (oldIndex > -1)
                {
                    itemsSource.Move(oldIndex, newIndex);
                }
                else
                {
                    itemsSource.Insert(newIndex, data);
                }

                // Set the Effects property so that the call to DoDragDrop will return 'Move'.
                e.Effects = DragDropEffects.Move;
            }
        }