I'm trying to drag items from a TreeGridView to a RadGridView, such that a single item will be stored in a single cell.
I have predefined columns with headers "A" to "Z" and want to drop items from the treeview to a single column, i.e. drop an item to column A and another item to column H, such that the rest of the columns are empty.
All of this should happen on a single row under the headers. I also don't want to be able to drag the column headers.
Are there any good solutions to this problem? I'm not sure what to do. Maybe there is a better View to use?
This is what I have so far:
Example.xaml.cs
Example.xaml
I have predefined columns with headers "A" to "Z" and want to drop items from the treeview to a single column, i.e. drop an item to column A and another item to column H, such that the rest of the columns are empty.
All of this should happen on a single row under the headers. I also don't want to be able to drag the column headers.
Are there any good solutions to this problem? I'm not sure what to do. Maybe there is a better View to use?
This is what I have so far:
Example.xaml.cs
using System;using System.Collections;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Windows;using System.Windows.Media;using Telerik.Windows.Controls;using Telerik.Windows.Controls.DragDrop;using Telerik.Windows.Controls.TreeView;using System.Windows.Controls;using System.Windows.Data;namespace Telerik.Windows.Examples.DragAndDrop.WPF.TreeToGrid{ public partial class Example : System.Windows.Controls.UserControl { MyCollection results = new MyCollection(); public Example() { InitializeComponent(); // Set the items source of the controls: allProductsView.ItemsSource = CategoryViewModel.Generate(); //IList orderSource = new ObservableCollection<string>(); //orderView.ItemsSource = orderSource; //foreach (ProductViewModel product in ProductViewModel.Generate(6)) //{ // wishlistSource.Add(product); //} // Allow dropping into the ListBox and GridView only if the // dragged items are all products: RadDragAndDropManager.AddDropQueryHandler(orderView, OnDropQuery); // Change the drag cue and choose an action for the sucessful drop // in the Order GridView: RadDragAndDropManager.AddDropInfoHandler(orderView, OnGridViewDropInfo); // Allow dragging of the Wishlist and Order items: RadDragAndDropManager.AddDragQueryHandler(orderView, OnOrderDragQuery); // Handle the case when items are dragged away from the ListBox // and the Order: RadDragAndDropManager.AddDragInfoHandler(orderView, OnOrderDragInfo); List<String> details = new List<string>(); char a = 'A'; char z = 'Z'; for (char cntr = a; cntr <= z; cntr++) { details.Add(cntr + ""); } results.Add(details); AddColumns(details); //-----set binding here or in Xaml------------------------ Binding binding = new Binding(); binding.Source = results; orderView.SetBinding(RadGridView.ItemsSourceProperty, binding); } private void AddColumns(List<String> myColumns) { //RadGridView viewLayout = new RadGridView(); //GridView viewLayout = new GridView(); for (int i = 0; i < myColumns.Count; i++) { orderView.Columns.Add(new Telerik.Windows.Controls.GridViewColumn { Header = myColumns[i], IsResizable = false, //BindingGroup = new BindingGroup(), //DisplayMemberBinding = new Binding(" ") }); } orderView.CanUserInsertRows = false; } private void OnOrderDragInfo(object sender, DragDropEventArgs e) { IEnumerable draggedItems = e.Options.Payload as IEnumerable; if (e.Options.Status == DragStatus.DragInProgress) { //Set up a drag cue: TreeViewDragCue cue = new TreeViewDragCue(); //Here we need to choose a template for the items: cue.ItemTemplate = this.Resources["ProductTemplate"] as DataTemplate; cue.ItemsSource = draggedItems; e.Options.DragCue = cue; } else if (e.Options.Status == DragStatus.DragComplete) { IList source = this.orderView.ItemsSource as IList; foreach (object draggedItem in draggedItems) { source.Remove(draggedItem); } } } private void OnOrderDragQuery(object sender, DragDropQueryEventArgs e) { if (this.orderView != null) { IList selectedItems = this.orderView.SelectedItems; e.QueryResult = selectedItems.Count > 0; e.Options.Payload = selectedItems; } e.QueryResult = true; e.Handled = true; } private void OnGridViewDropInfo(object sender, DragDropEventArgs e) { ICollection draggedItems = e.Options.Payload as ICollection; // Get the drag cu that the TreeView or we have created TreeViewDragCue cue = e.Options.DragCue as TreeViewDragCue; if (e.Options.Status == DragStatus.DropPossible) { // Set a suitable text: cue.DragActionContent = String.Format("Add {0} item{1} to Order", draggedItems.Count, draggedItems.Count > 1 ? "s" : String.Empty); cue.IsDropPossible = true; this.orderView.Background = this.Resources["DropPossibleBackground"] as Brush; } else if (e.Options.Status == DragStatus.DropImpossible) { cue.DragActionContent = null; cue.IsDropPossible = false; } else if (e.Options.Status == DragStatus.DropComplete) { IList items = this.orderView.ItemsSource as IList; foreach (object draggedItem in draggedItems) { items.Add(draggedItem); } } if (e.Options.Status != DragStatus.DropPossible) { this.orderView.Background = new SolidColorBrush(Colors.White); } } private void OnDropQuery(object sender, DragDropQueryEventArgs e) { // We allow drop only if the dragged items are products: ICollection draggedItems = e.Options.Payload as ICollection; bool result = draggedItems.Cast<object>().All((object item) => item is ProductViewModel); e.QueryResult = result; e.Handled = true; // Note that here we agree to accept a drop. We will be notified // in the DropInfo event whether a drop is actually possible. } } public class ExampleTemplateSelector : DataTemplateSelector { public override DataTemplate SelectTemplate(object item, DependencyObject container) { if (item is ProductViewModel) { return ProductTemplate; } else if (item is CategoryViewModel) { return CategoryTemplate; } return null; } public DataTemplate ProductTemplate { get; set; } public DataTemplate CategoryTemplate { get; set; } } public class CategoryViewModel { public static IList Generate() { var apiOutput1 = new CategoryViewModel(); apiOutput1.Title = "List items"; apiOutput1.Items.Add("Item1"); apiOutput1.Items.Add("Item2"); var apiOutput2 = new CategoryViewModel(); apiOutput2.Title = "Item Price"; apiOutput2.Items.Add("Price1"); apiOutput2.Items.Add("Price2"); var userDefFields = new CategoryViewModel(); userDefFields.Title = "User fields"; userDefFields.Items.Add("Field1"); userDefFields.Items.Add("Field2"); IList result = new List<object>(); result.Add(apiOutput1); result.Add(apiOutput2); result.Add(userDefFields); return result; } public CategoryViewModel() { Items = new ObservableCollection<object>(); } public string Title { get; set; } public IList Items { get; set; } } public class ProductViewModel { public ProductViewModel(string name, string desc) { Name = name; Description = desc; } public string Name { get; set; } public string Description { get; set; } public override string ToString() { return Name.ToString(); } } public class MyCollection : ObservableCollection<List<string>> { public MyCollection() : base() { } }}Example.xaml
<UserControl x:Class="Telerik.Windows.Examples.DragAndDrop.WPF.TreeToGrid.Example" xmlns:nav="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:gridViewElements="clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView" xmlns:example="clr-namespace:Telerik.Windows.Examples.DragAndDrop.WPF.TreeToGrid" xmlns:dragDrop="clr-namespace:Telerik.Windows.Controls.DragDrop;assembly=Telerik.Windows.Controls"> <UserControl.Resources> <telerik:MetroColors x:Key="MetroColors" /> <SolidColorBrush x:Key="AccentBrush" Color="{Binding Source={StaticResource MetroColors}, Path=Palette.AccentColor}" /> <SolidColorBrush x:Key="BasicBrush" Color="{Binding Source={StaticResource MetroColors}, Path=Palette.BasicColor}" /> <SolidColorBrush x:Key="StrongBrush" Color="{Binding Source={StaticResource MetroColors}, Path=Palette.StrongColor}" /> <SolidColorBrush x:Key="MainBrush" Color="{Binding Source={StaticResource MetroColors}, Path=Palette.MainColor}" /> <SolidColorBrush x:Key="MarkerBrush" Color="{Binding Source={StaticResource MetroColors}, Path=Palette.MarkerColor}" /> <SolidColorBrush x:Key="ValidationBrush" Color="{Binding Source={StaticResource MetroColors}, Path=Palette.ValidationColor}" /> <DataTemplate x:Key="WishlistProduct"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Name}" FontWeight="Bold" /> <TextBlock Text=", (" Foreground="Gray" /> <TextBlock Text="{Binding UnitPrice}" Foreground="Gray" /> <TextBlock Text=")" Foreground="Gray" /> </StackPanel> </DataTemplate> <HierarchicalDataTemplate x:Key="CategoryTemplate" ItemsSource="{Binding Items}"> <StackPanel Orientation="Horizontal"> <Image Width="16" Height="16" Source="../../Images/DragAndDrop/folder_icon.png" Margin="3" VerticalAlignment="Center" /> <TextBlock Text="{Binding Title}" Foreground="{StaticResource MainBrush}" Margin="2" VerticalAlignment="Center" /> </StackPanel> </HierarchicalDataTemplate> <DataTemplate x:Key="ProductTemplate"> <DockPanel Margin="2" MaxWidth="200"> <TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="{StaticResource MainBrush}" DockPanel.Dock="Top" /> <!--<TextBlock Text="{Binding Description}" DockPanel.Dock="Left" Margin="2 0 0 0" Foreground="{StaticResource MainBrush}" TextWrapping="Wrap" /> --> </DockPanel> </DataTemplate> <example:ExampleTemplateSelector x:Key="ExampleTemplateSelector" CategoryTemplate="{StaticResource CategoryTemplate}" ProductTemplate="{StaticResource ProductTemplate}" /> <Style TargetType="nav:RadTreeViewItem" x:Key="TreeViewItemStyle"> <Setter Property="IsExpanded" Value="True" /> </Style> <!--Note: With this style we make the ListBoxItems draggable:--> <Style TargetType="gridViewElements:GridViewRow" x:Key="OrderItemStyle"> <Setter Property="dragDrop:RadDragAndDropManager.AllowDrag" Value="True" /> </Style> </UserControl.Resources> <Grid x:Name="LayoutRoot"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="3*" /> </Grid.ColumnDefinitions> <!--All Products--> <Border BorderBrush="#C8C9CC" BorderThickness="2" CornerRadius="6" Margin="46 46 0 46" Background="White"> <DockPanel> <Border DockPanel.Dock="Top" Background="{StaticResource AccentBrush}" CornerRadius="4 4 0 0"> <TextBlock Text="All Products" Margin="20 5 5 5" Foreground="{StaticResource MainBrush}" FontSize="14"/> </Border> <nav:RadTreeView x:Name="allProductsView" ItemTemplateSelector="{StaticResource ExampleTemplateSelector}" ItemContainerStyle="{StaticResource TreeViewItemStyle}" IsDragDropEnabled="True" Background="{StaticResource AccentBrush}" Padding="5"/> </DockPanel> </Border> <!--Order--> <Border BorderBrush="#C8C9CC" BorderThickness="2" CornerRadius="6" Margin="46 46 0 46" Background="White" Grid.Column="1"> <DockPanel> <Border DockPanel.Dock="Top" Background="{StaticResource AccentBrush}" CornerRadius="4 4 0 0"> <TextBlock Text="Order" Foreground="{StaticResource MainBrush}" Margin="20 5 5 5" FontSize="14" /> </Border> <!--NOTE: The GridView is a drop target, we set the AllowDrop to true.--> <telerik:RadGridView x:Name="orderView" dragDrop:RadDragAndDropManager.AllowDrop="True" CanUserInsertRows="False" IsReadOnly="True" CanUserFreezeColumns="False" ShowGroupPanel="False"/> </DockPanel> </Border> </Grid></UserControl>