This is a migrated thread and some comments may be shown as answers.

Handle ItemReorderComplete

8 Answers 48 Views
ListView
This is a migrated thread and some comments may be shown as answers.
John
Top achievements
Rank 1
John asked on 23 Feb 2017, 07:47 AM

Hi,

No event is fired when an item is reordered. I know there is a command but i can't get it to work. What is the easiest way to implement this command. I am using caliburn micro but it is no problem to handle it in the code behind of the xaml.

Thanks

8 Answers, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 23 Feb 2017, 07:19 PM
Hello John,

You can indeed do this in the view model. Use the CollectionChanged event of the ObservableCollection you are using for the RadListView's ItemsSource

The RadListView updates the bound items when an item is reordered, thus the ObservableCollection will fire the CollectionChanged event. In there you can determine what the type of change was by using the event args's Action property.

Here's a short example:

// your items source
private ObservableCollection<string> myItems;
 
// hook into the CollectionChanged event
myItems.CollectionChanged += myItems_CollectionChanged;
 
// event handler
private void myItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            break;
        case NotifyCollectionChangedAction.Move:
            break;
        case NotifyCollectionChangedAction.Remove:
            break;
        case NotifyCollectionChangedAction.Replace:
            break;
        case NotifyCollectionChangedAction.Reset:
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
}


Let us know if you have any further questions

Regards,
Lance | Tech Support Engineer, Sr.
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
John
Top achievements
Rank 1
answered on 23 Feb 2017, 09:54 PM
Thanks for your example. 
When i reorder an item it goes back to it's original place and the CollectionChanged event is not fired. Am i forgetting something?
0
Lance | Manager Technical Support
Telerik team
answered on 23 Feb 2017, 11:04 PM
Hello John,

You haven't shared your code so I can't tell exactly what's wrong, but it could just be a simple misconfiguration. 

Here's what you need for Reordering to work:

<telerikData:RadListView ItemsSource="{Binding MyItems}"
     ReorderMode="Handle"
     IsItemReorderEnabled="True"/>


Regards,
Lance | Tech Support Engineer, Sr.
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Lance | Manager Technical Support
Telerik team
answered on 23 Feb 2017, 11:14 PM
Hello John,

Just a quick follow up, I was able to reproduce what you're seeing using a File > New. I'm not sure what is happening here, so I'm escalating this to the UI for UWP dev team for further investigation.

They'll get back to you once they've taken a look at the issue, thank you for reporting this.

Regards,
Lance | Tech Support Engineer, Sr.
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Accepted
Lance | Manager Technical Support
Telerik team
answered on 23 Feb 2017, 11:39 PM
Hi John,

I have a solution for you. The reason you're seeing the reorder not complete is because you need to have a command that reports CanExecute=True.

It would be better if I just gave you the full code to get it running. 

First, lets define the item model

public class ItemViewModel : ViewModelBase
{
        private string title;
        private string summary;
 
        public string Title
        {
            get { return title; }
            set { title = value; OnPropertyChanged();}
        }
 
        public string Summary
        {
            get { return summary; }
            set { summary = value; OnPropertyChanged();}
        }
}


Next let's define the MainViewModel

public class MainPageViewModel : ViewModelBase
{
        private ObservableCollection<ItemViewModel> myItems;
 
        public MainPageViewModel()
        {
            // This is the reorder command
            this.ReorderItemsCommand = new DelegateCommand(ReorderItems);
 
            // load in some sample items
            for (int i = 0; i < 30; i++)
            {
                MyItems.Add(new ItemViewModel
                {
                    Title = $"Item {i}",
                    Summary = $"This is a summary for Item {i}"
                });
            }
 
            myItems.CollectionChanged += MyItems_CollectionChanged;
        }
 
        private void MyItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            ItemViewModel item = null;
 
            if (e.NewItems?.Count > 0)
            {
                item = e.NewItems[0] as ItemViewModel;
            }
 
            if (e.OldItems?.Count > 0)
            {
                item = e.OldItems[0] as ItemViewModel;
            }
 
            Debug.WriteLine($"CollectionChanged Action: {e.Action} for {item?.Title}");
        }
 
        public ObservableCollection<ItemViewModel> MyItems
        {
            get { return myItems ?? (myItems = new ObservableCollection<ItemViewModel>()); }
            set { myItems = value; OnPropertyChanged();}
        }
 
        public ICommand ReorderItemsCommand { get; set; }
 
 
        // Method where the reordering occurs, add a using Telerik.UI.Xaml.Controls.Data.ListView.Commands to resolve ItemReorderCompleteContext
        private void ReorderItems(object parameter)
        {
            var context = parameter as ItemReorderCompleteContext;
 
            if (context == null)
                return;
 
            var item = context.Item as ItemViewModel;
            var destItem = context.DestinationItem as ItemViewModel;
 
            int sourceIndex = this.MyItems.IndexOf(item);
            int targetIndex = this.MyItems.IndexOf(destItem);
 
            this.MyItems.Move(sourceIndex, targetIndex);
}


Next here's the MainPage xaml. I have highlighted the command that enables the reordering

<Page x:Name="Page"
    x:Class="JohnReorderDemo.MainPage"
    xmlns:data="using:Telerik.UI.Xaml.Controls.Data"
    xmlns:viewModels="using:JohnReorderDemo.ViewModels"
    xmlns:commands="using:Telerik.UI.Xaml.Controls.Data.ListView.Commands"
    mc:Ignorable="d">
 
    <Page.Resources>
        <viewModels:MainPageViewModel x:Key="viewModel" />
    </Page.Resources>
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
          DataContext="{StaticResource viewModel}">
         
        <data:RadListView ItemsSource="{Binding MyItems}"
                          ReorderMode="Handle"
                          IsItemReorderEnabled="True">
            <data:RadListView.Commands>
                <commands:ListViewUserCommand Id="ItemReorderComplete"
                                              Command="{Binding ReorderItemsCommand, Source={StaticResource viewModel}}" />
            </data:RadListView.Commands>
            <data:RadListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Title}"
                               Style="{StaticResource TitleTextBlockStyle}" />
                </DataTemplate>
            </data:RadListView.ItemTemplate>
        </data:RadListView>
    </Grid>
</Page>


When you run that, the the Command reports CanExecute by default which allows the RadListView to complete the reorder. You'll also see in the debug output my debug note from the CollectionChanged event handler.


Note: I'm pretty sure Caliburn Micro has an implementation of DelegateCommand, but in case it doesn't, here's a simple one you can use

public class DelegateCommand : ICommand
{
        private readonly Predicate<object> canExecute;
        private readonly Action<object> action;
 
        public event EventHandler CanExecuteChanged;
 
        public DelegateCommand(Action<object> execute) : this(execute, null)
        {
        }
 
        public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
        {
            this.action = execute;
            this.canExecute = canExecute;
        }
 
        public bool CanExecute(object parameter)
        {
            if (canExecute == null)
            {
                return true;
            }
 
            return canExecute(parameter);
        }
 
        public void Execute(object parameter)
        {
            action(parameter);
        }
 
        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }
}

Let me know if you still have trouble after adding the command.

Regards,
Lance | Tech Support Engineer, Sr.
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
John
Top achievements
Rank 1
answered on 24 Feb 2017, 06:41 AM

Tanks! 

This example works but know i have to try to get it to work my project. For now i am having trouble setting the source of the command binding because i can't do it as in your example. I'll let you know when it works.

0
John
Top achievements
Rank 1
answered on 24 Feb 2017, 07:58 AM
I add the command in the baseclass of the view and now it works. Thanks again.
0
Lance | Manager Technical Support
Telerik team
answered on 24 Feb 2017, 03:01 PM
Hi John,

I'm happy to see you're up and running! Let us know if you have any further trouble.

Regards,
Lance | Tech Support Engineer, Sr.
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
ListView
Asked by
John
Top achievements
Rank 1
Answers by
Lance | Manager Technical Support
Telerik team
John
Top achievements
Rank 1
Share this question
or