Exemple #1
0
        void SetItemsInViewModelColumns(ObservableCollection <ColumnViewModel> columns)
        {
            Dictionary <object, ColumnViewModel> quickColumnsFromId      = new Dictionary <object, ColumnViewModel>();
            Dictionary <object, IEnumerable <ItemViewModel> > listFromId = new Dictionary <object, IEnumerable <ItemViewModel> >();
            ObservableCollection <ItemViewModel> remainingItems          = new ObservableCollection <ItemViewModel>();
            ColumnViewModel unclassifiedColumn = null;

            foreach (ColumnViewModel column in columns)
            {
                column.UnalteredItemsCollection.Clear();
                if (column.ColumnDefinition.Id != null)
                {
                    quickColumnsFromId.Add(column.ColumnDefinition.Id, column);
                    listFromId.Add(column.ColumnDefinition.Id, new ObservableCollection <ItemViewModel>());
                }
                else
                {
                    unclassifiedColumn = column;
                    unclassifiedColumn.IsUnclassifiedColumn = true;
                }
            }
            if (ItemsSource != null)
            {
                foreach (Object item in ItemsSource)
                {
                    //Get the id from the item and add a Binding to it so we can update it when necessary:
                    object        id;
                    ItemViewModel itemViewModel = new ItemViewModel(item, this);
                    Binding       binding       = new Binding(ColumnMemberPath);
                    binding.Source = item;
                    binding.Mode   = BindingMode.TwoWay;
                    BindingOperations.SetBinding(itemViewModel, ItemViewModel.ItemColumnIdProperty, binding);
                    //itemViewModel.SetBinding(ItemViewModel.ItemColumnIdProperty, binding);
                    id = itemViewModel.ItemColumnId;
                    //todo: handle the case where the Binding is broken.

                    //Add a binging to get the ItemOrder:
                    Binding orderBinding = new Binding(OrderMemberPath);
                    orderBinding.Source = item;
                    orderBinding.Mode   = BindingMode.TwoWay;
                    BindingOperations.SetBinding(itemViewModel, ItemViewModel.ItemOrderProperty, orderBinding);
                    //itemViewModel.SetBinding(ItemViewModel.ItemOrderProperty, orderBinding);

                    //Add the item to the list for the corresponding id:
                    if (id != null && listFromId.ContainsKey(id))
                    {
                        ((ObservableCollection <ItemViewModel>)listFromId[id]).Add(itemViewModel);
                    }
                    else
                    {
                        remainingItems.Add(itemViewModel);
                    }
                }

                foreach (object id in listFromId.Keys)
                {
                    quickColumnsFromId[id].UnalteredItemsCollection = (ObservableCollection <ItemViewModel>)listFromId[id];
                }

                if (unclassifiedColumn != null)
                {
                    //we should always enter this "if"
                    unclassifiedColumn.UnalteredItemsCollection = remainingItems;
                }
            }
        }
        public void Execute(object parameter)
        {
            //Version using Drop event:
            var param = parameter as System.Windows.DragEventArgs;

            if (param != null)
            {
                var castedParameter = param.Data.GetData("ItemDragEventArgs") as ItemDragEventArgs;

                int newItemOrder = -1;

                //We get the item on which the element was dropped:
                var elements = VisualTreeHelper.FindElementsInHostCoordinates(param.GetPosition(null).Position, _column.ColumnDefinition._kanBanControl);
                FrameworkElement elementDroppedOn = elements.ElementAt(0) as FrameworkElement;
                while (elementDroppedOn != null &&                                                                                //we go up the visual tree until we reached the root or...
                       (elementDroppedOn.DataContext == null || elementDroppedOn.DataContext.GetType() != typeof(ItemViewModel))) //...until we found an element that has the ItemViewModel as DataContext
                {
                    elementDroppedOn = elementDroppedOn.Parent as FrameworkElement;
                }
                if (elementDroppedOn != null)
                {
                    //todo: find a way to know in which half of the DropElement the dragged element was dropped.
                    //      We could do with comparing the position at which it was dropped with the position of the root of the item card
                    //          (but it need us to find said root - could be done by going up the visual tree until we find an element whose DataContext is not an ItemViewModel
                    //          -> the last one with the ItemViewModel should be the root element)
                    //      We could try to know it the cursor was on the Header or the body of the card.


                    //for now, we will consider the element dropped above:
                    newItemOrder = ((ItemViewModel)elementDroppedOn.DataContext).ItemOrder + 1; //Reminder: we have chosen to have the items with the bigger order number higher on the displayed list.
                }

                //Version using ItemDragCompleted event (this one doesn't seem good because the sender is the column from which the item comes):
                //var castedParameter = parameter as ItemDragEventArgs;
                //if(castedParameter != null)
                //{
                SelectionCollection selectionCollection = castedParameter.Data as SelectionCollection;
                if (selectionCollection.Count > 0)
                {
                    Selection        selection     = selectionCollection.ElementAt(0); //we can only drag one item so it is at the position 0.
                    FrameworkElement container     = selection.Item as FrameworkElement;
                    ItemViewModel    itemViewModel = container.DataContext as ItemViewModel;
                    if (itemViewModel != null)
                    {
                        itemViewModel.ItemOrder = newItemOrder;
                        UpdateItemOrders(newItemOrder);

                        itemViewModel.ItemColumnId = _column.ColumnDefinition.Id;

                        //force a refresh of the KanBanControl:
                        //todo: find a way to only refresh the Column itself.
                        var kanBanControl = _column.ColumnDefinition._kanBanControl;
                        var columns       = kanBanControl.Columns;
                        kanBanControl.Columns = null;
                        kanBanControl.Columns = columns;

                        // Raise the "ItemMoved" event:
                        kanBanControl.OnItemMoved(itemViewModel);

                        //keep the following to only refresh the column itself. It cannot be used properly currently as it causes a bug where the items are duplicated.
                        ////refresh the elements of the column:
                        //_column.Dispatcher.BeginInvoke( () =>
                        //{
                        //    _column.UnalteredItemsCollection.Add(itemViewModel); //we add the item manually because the whole collection was not refreshed in the process. This should change with Smooth refresh.
                        //    _column.SetOrderedItemsCollection();
                        //    });
                        //_column.SetOrderedItemsCollection();
                    }
                }
            }
        }