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>