Intersoft ClientUI 8 > ClientUI Controls > Control Library > Advanced Content Controls Overview > UXListBox > Walkthrough: Enable Drag-drop Functionality in UXListBox |
This walkthrough shows how to drag and drop an object, which is triggered from images that are bound to DragDrop event.
In this walkthrough, you perform the following tasks:
You need the following components to complete this walkthrough:
The first step is to create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template in Visual Studio.
Next, you will create the Contact model class that represent the data entity used in this walkthrough.
This section shows you how to create the Contact model class that represents the data entity used in this walkthrough. To create the Contact model class, see Walkthrough: Creating Model for Contact Data.
Next, you will create the view for your simple contacts list application.
This section steps you through the process of creating a page that uses a variety of ClientUI controls such as UXListBox. The UXListBox is used to display a collection of Contact data.
For more information on how to add a new item in Visual Studio, see Walkthrough: Add New Item such as Page, Dialog Box and Window in VS 2010 |
Properties | Value |
---|---|
Content | Available Personnel |
Intersoft:DockPanel.Dock | Top |
HorizontalContentAlignment | Left |
Properties | Value |
---|---|
Height | 300 |
AllowDropItem | True |
AllowMoveItem | True |
AllowRemoveItem | True |
HorizontalAlignment | Stretch |
ItemContentType | ContentAndImage |
ItemImageHeight | 64 |
ItemImageWidth | 64 |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Intersoft:DockPanel VerticalAlignment="Center" HorizontalAlignment="Center"> <Intersoft:DockPanel FillChildMode="Custom" Width="270" Margin="4"> <Intersoft:StylishLabel Content="Available Personnel" Intersoft:DockPanel.Dock="Top" HorizontalContentAlignment="Left"/> <Intersoft:UXSeparator Intersoft:DockPanel.Dock="Top"/> <Grid Margin="12" Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox1" Height="300" AllowDropItem="True" AllowMoveItem="True" AllowRemoveItem="True" HorizontalAlignment="Stretch" ItemContentType="ContentAndImage" ItemImageHeight="64" ItemImageWidth="64" /> </Grid> </Intersoft:DockPanel> </Intersoft:DockPanel> </Grid> |
XAML |
Copy Code
|
---|---|
<Intersoft:DockPanel VerticalAlignment="Center" HorizontalAlignment="Center"> ... <Intersoft:DockPanel FillChildMode="Custom" Width="270" Margin="4"> <Intersoft:StylishLabel Content="Out-Sourced Personnel" Intersoft:DockPanel.Dock="Top" HorizontalContentAlignment="Left"/> <Intersoft:UXSeparator Intersoft:DockPanel.Dock="Top"/> <Grid Margin="12" Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox2" Height="300" AllowDropItem="True" AllowMoveItem="True" AllowRemoveItem="True" HorizontalAlignment="Stretch" ItemContentType="ContentAndImage" ItemImageHeight="64" ItemImageWidth="64" /> </Grid> </Intersoft:DockPanel> </Intersoft:DockPanel> |
In the previous sections, you have learned how to create the Model and ViewModel classes, as well as the View that contains the user interface and controls used in this walkthrough. This section shows how to instantiate the ViewModel in the XAML page and bind the UI elements to the properties in the ViewModel such as the items source and data context.
C# |
Copy Code
|
---|---|
public class ContactViewModel : ViewModelBase { } |
C# |
Copy Code
|
---|---|
// Fields private Contact _selectedItem = null; // Views public ObservableCollection<Contact> Contacts { get; set; } public ObservableCollection<Contact> ContactsData { get; set; } public ObservableCollection<Contact> OutsourceData { get; set; } |
C# |
Copy Code
|
---|---|
DragDropUXListBox public ContactViewModel() { this.LoadContacts(); } private void LoadContacts() { // loads contact data from xml file StreamResourceInfo resource = System.Windows.Application.GetResourceStream( new Uri("DragDropUXListBox;component/Assets/Data/ContactDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(resource.Stream); var contacts = from x in doc.Descendants("Customer") select new Contact(x); this.Contacts = new ObservableCollection<Contact>(); this.ContactsData = new ObservableCollection<Contact>(); this.OutsourceData = new ObservableCollection<Contact>(); foreach (Contact contact in contacts) { contact.SetPhoto(this.Contacts.Count.ToString()); this.Contacts.Add(contact); this.ContactsData.Add(contact); } resource.Stream.Close(); } |
In the previous sections, you have learned how to create the Model and ViewModel classes, as well as the View that contains the user interface and controls used in this walkthrough. This section shows how to instantiate the ViewModel in the XAML page and bind the UI elements to the properties in the ViewModel such as the data context, template and event.
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage.Resources> <ViewModels:ContactViewModel x:Key="ContactsData"/> </Intersoft:UXPage.Resources> |
XAML |
Copy Code
|
---|---|
<Intersoft:DockPanel FillChildMode="Custom" Width="270" Margin="4"> ... <Grid Margin="12" DataContext="{StaticResource ContactsData}" Intersoft:DockPanel.IsFillElement="True"> ... </Grid> </Intersoft:DockPanel> |
XAML |
Copy Code
|
---|---|
<Grid Margin="12" DataContext="{StaticResource ContactsData}" Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox1" Height="300" AllowDropItem="True" AllowMoveItem="True" AllowRemoveItem="True" HorizontalAlignment="Stretch" ItemContentType="ContentAndImage" ItemImageHeight="64" ItemImageWidth="64" SelectedValuePath="Id" ItemsSource="{Binding ContactsData}" IsTextSearchEnabled="True" DisplayMemberPath="Name" ImageMemberPath="Photo" /> </Grid> |
XAML |
Copy Code
|
---|---|
<Grid Margin="12" DataContext="{StaticResource ContactsData}" Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox2" Height="300" AllowDropItem="True" AllowMoveItem="True" AllowRemoveItem="True" HorizontalAlignment="Stretch" ItemContentType="ContentAndImage" ItemImageHeight="64" ItemImageWidth="64" SelectedValuePath="Id" ItemsSource="{Binding OutsourceData}" IsTextSearchEnabled="True" DisplayMemberPath="Name" ImageMemberPath="Photo" /> </Grid> |
In this walkthrough, you have learned how to create ClientUI MVVM project using project template, and create the classes and page based on the Model, View and ViewModel pattern. You also learned how to bind UXListBox to a collection of data, and then Attach the UXListBox to a DragDrop event in the ViewModel which can move the object into another UXListBox.
This section lists the complete code used in this walkthrough.
C# |
Copy Code
|
---|---|
using System; using System.Text.RegularExpressions; using System.Xml.Linq; using DragDropUXListBox.ViewModels; namespace DragDropUXListBox.Models { public class Contact : ModelBase { // rfc 2282 compliance email address regex private const string EmailPattern = @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"; #region Constructors public Contact() { } public Contact(XElement x) : this() { this._id = x.Element("Id").Value.Trim(); this._name = x.Element("Name").Value.Trim(); this._email = x.Element("Email").Value.Trim(); this._address = x.Element("Address").Value.Trim(); this._state = x.Element("State").Value.Trim(); this._zipCode = x.Element("ZipCode").Value.Trim(); this._phone = x.Element("Phone").Value.Trim(); this._fax = x.Element("Fax").Value.Trim(); this._cell = x.Element("Cell").Value.Trim(); this._blog = x.Element("Blog").Value.Trim(); this._twitter = x.Element("Twitter").Value.Trim(); this._website = x.Element("Website").Value.Trim(); } #endregion #region Fields private string _name = string.Empty; private string _address = string.Empty; private string _phone = string.Empty; private string _cell = string.Empty; private string _id = string.Empty; private string _email = string.Empty; private string _fax = string.Empty; private string _blog = string.Empty; private string _twitter = string.Empty; private string _website = string.Empty; private string _state = string.Empty; private string _zipCode = string.Empty; private Uri _photo = null; #endregion #region Properties public string Name { get { return this._name; } set { if (this._name != value) { this._name = value; this.ClearError("Name"); this.OnPropertyChanged("Name"); } } } public string Address { get { return this._address; } set { if (this._address != value) { this._address = value; this.ClearError("Address"); this.OnPropertyChanged("Address"); } } } public string Phone { get { return this._phone; } set { if (this._phone != value) { this._phone = value; this.OnPropertyChanged("Phone"); } } } public string Cell { get { return this._cell; } set { if (this._cell != value) { this._cell = value; this.OnPropertyChanged("Cell"); } } } public string Id { get { return this._id; } set { if (this._id != value) { this._id = value; this.OnPropertyChanged("Id"); } } } public string Email { get { return this._email; } set { if (this._email != value) { this._email = value; this.OnPropertyChanged("Email"); } } } public string Fax { get { return this._fax; } set { if (this._fax != value) { this._fax = value; this.OnPropertyChanged("Fax"); } } } public string Blog { get { return this._blog; } set { if (this._blog != value) { this._blog = value; this.OnPropertyChanged("Blog"); } } } public string Twitter { get { return this._twitter; } set { if (this._twitter != value) { this._twitter = value; this.OnPropertyChanged("Twitter"); } } } public string Website { get { return this._website; } set { if (this._website != value) { this._website = value; this.OnPropertyChanged("Website"); } } } public string State { get { return this._state; } set { if (this._state != value) { this._state = value; this.OnPropertyChanged("State"); } } } public string ZipCode { get { return this._zipCode; } set { if (this._zipCode != value) { this._zipCode = value; this.ClearError("ZipCode"); this.OnPropertyChanged("ZipCode"); } } } public Uri Photo { get { return this._photo; } set { if (this._photo != value) { this._photo = value; this.OnPropertyChanged("Photo"); } } } #endregion #region Methods public Contact Clone() { return new Contact() { Id = this._id, Name = this._name, Email = this._email, Address = this._address, State = this._state, ZipCode = this._zipCode, Phone = this._phone, Cell = this._cell, Fax = this._fax, Blog = this._blog, Twitter = this._twitter, Website = this._website, Photo = this._photo }; } public bool Validate(bool notifyDataError) { bool isValid = true; if (notifyDataError) this.ClearAllErrors(); if (string.IsNullOrEmpty(this.Id)) { isValid = false; if (notifyDataError) this.SetError("Id", "ID is required"); } if (string.IsNullOrEmpty(this.Name)) { isValid = false; if (notifyDataError) this.SetError("Name", "Please specify a name"); } if (string.IsNullOrEmpty(this.Email)) { isValid = false; if (notifyDataError) this.SetError("Email", "Please specify an email address"); } else { if (notifyDataError) { if (!Regex.IsMatch(this._email, Contact.EmailPattern)) this.SetError("Email", "Invalid email address"); } } if (string.IsNullOrEmpty(this.Phone)) { isValid = false; if (notifyDataError) this.SetError("Number", "Please specify a phone number"); } return isValid; } public void SetPhoto(string uri) { this.Photo = new Uri("/DragDropUXListBox;component/Assets/Images/" + uri + ".jpg", UriKind.RelativeOrAbsolute); } public void SetPhoto(Uri uri) { this.Photo = uri; } #endregion } } |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Intersoft="http://intersoft.clientui.com/schemas" xmlns:ViewModels="clr-namespace:DragDropUXListBox.ViewModels" mc:Ignorable="d" x:Class="DragDropUXListBox.Views.Contact" Title="Contact Page" d:DesignWidth="640" d:DesignHeight="480"> <Intersoft:UXPage.Resources> <ViewModels:ContactViewModel x:Key="ContactsData"/> </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot"> <Intersoft:DockPanel VerticalAlignment="Center" HorizontalAlignment="Center"> <Intersoft:DockPanel FillChildMode="Custom" Width="270" Margin="4"> <Intersoft:StylishLabel Content="Available Personnel" Intersoft:DockPanel.Dock="Top" HorizontalContentAlignment="Left"/> <Intersoft:UXSeparator Intersoft:DockPanel.Dock="Top"/> <Grid Margin="12" DataContext="{StaticResource ContactsData}" Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox1" Height="300" AllowDropItem="True" AllowMoveItem="True" AllowRemoveItem="True" HorizontalAlignment="Stretch" ItemContentType="ContentAndImage" ItemImageHeight="64" ItemImageWidth="64" SelectedValuePath="Id" ItemsSource="{Binding ContactsData}" IsTextSearchEnabled="True" DisplayMemberPath="Name" ImageMemberPath="Photo" /> </Grid> </Intersoft:DockPanel> <Intersoft:DockPanel FillChildMode="Custom" Width="270" Margin="4"> <Intersoft:StylishLabel Content="Out-Sourced Personnel" Intersoft:DockPanel.Dock="Top" HorizontalContentAlignment="Left"/> <Intersoft:UXSeparator Intersoft:DockPanel.Dock="Top"/> <Grid Margin="12" DataContext="{StaticResource ContactsData}" Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox2" Height="300" AllowDropItem="True" AllowMoveItem="True" AllowRemoveItem="True" HorizontalAlignment="Stretch" ItemContentType="ContentAndImage" ItemImageHeight="64" ItemImageWidth="64" SelectedValuePath="Id" ItemsSource="{Binding OutsourceData}" IsTextSearchEnabled="True" DisplayMemberPath="Name" ImageMemberPath="Photo" /> </Grid> </Intersoft:DockPanel> </Intersoft:DockPanel> </Grid> </Intersoft:UXPage> |
C# |
Copy Code
|
---|---|
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Intersoft.Client.Framework.Input; using System.Collections.ObjectModel; using System.Linq; using System.Windows.Resources; using System.Xml.Linq; using DragDropUXListBox.Models; namespace DragDropUXListBox.ViewModels { public class ContactViewModel : ViewModelBase { // Fields private Contact _selectedItem = null; // Views public ObservableCollection<Contact> Contacts { get; set; } public ObservableCollection<Contact> ContactsData { get; set; } public ObservableCollection<Contact> OutsourceData { get; set; } public string ContactsCount { get { if (this.Contacts.Count == 0) return "No contacts"; else if (this.Contacts.Count == 1) return "1 contact"; else return this.Contacts.Count + " contacts"; } } // Selection, View States public Contact SelectedItem { get { return _selectedItem; } set { if (_selectedItem != value) { _selectedItem = value; OnPropertyChanged("SelectedItem"); InvalidateCommands(); } } } public ContactViewModel() { this.LoadContacts(); } private void LoadContacts() { // loads contact data from xml file StreamResourceInfo resource = System.Windows.Application.GetResourceStream( new Uri("DragDropUXListBox;component/Assets/Data/ContactDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(resource.Stream); var contacts = from x in doc.Descendants("Customer") select new Contact(x); this.Contacts = new ObservableCollection<Contact>(); this.ContactsData = new ObservableCollection<Contact>(); this.OutsourceData = new ObservableCollection<Contact>(); foreach (Contact contact in contacts) { contact.SetPhoto(this.Contacts.Count.ToString()); this.Contacts.Add(contact); this.ContactsData.Add(contact); } resource.Stream.Close(); } protected virtual void InvalidateCommands() { } } } |