Hi eveyone,
I think it may be so easy but I don't know how to find the RadlistBoxItem index on which is dropped (DropPosition) in RadListBox before adding the item to destination RadListBox.ItemsSource using DragDropBehavior.
Thank you.
7 Answers, 1 is accepted
One possible approach to achieve the desired is to create a custom ListBoxDragDropBehavior and override its Drop method. Inside it you could access the InsertIndex from the DragDropState:
public
class
CustomListBoxDragDropBehavior : ListBoxDragDropBehavior
{
public
override
void
Drop(DragDropState state)
{
var index = state.InsertIndex;
base
.Drop(state);
}
}
and in Xaml:
<
telerik:RadListBox
>
<
telerik:RadListBox.DragDropBehavior
>
<
local:CustomListBoxDragDropBehavior
/>
</
telerik:RadListBox.DragDropBehavior
>
</
telerik:RadListBox
>
Please, give it a try and let us know if the proposed approach helped you for your scenario.
We hope this will help you.
Regards,
Nasko
Telerik
Hi Nasko,
Thank you for your reply. I'm trying to develop an object similar to RadFieldList querying directly from database. So, as you know, I have to manage 5 listboxes. I couldn't find how to be able to manage them by overriding ListBoxDragDropBehavior's methods. Because I can not access to listboxes via these methods to check if the item is there. So I've decided to manipulate drag and drop operations (including drop prevention) through DragDropManager. If you have a similar sample for this purpose I would apriciate you for sharing with me.
Thank you...
Could you please share with us your custom implementation of the DragDrop behavior of the ListBoxes that you create using the DragDropManager?
Meanwhile, as another approach that we could suggest you is to handle the CollectionChanged event of the collection your ListBox is bound to. Thus as soon as an item is dropped inside the collection the vent will fire and you will be able to get its index.
We are looking forward to hearing from you.
Regards,
Nasko
Telerik
Hi Nasko,
Thank you for your quick reply. DragDropManager ​made me manipulate all scenarios. Especially it's so difficult to handle drag drop position values in RadWindow object. So I've choiced your advice. Now my app sample is like this.
public class FieldX
{
public int FieldID { get; set; }
public string FieldName { get; set; }
public FieldX Clone()
{
return new FieldX
{
FieldID = this.FieldID,
FieldName = this.FieldName,
};
}
}
<DataTemplate x:Key="ListBoxItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<telerik:RadButton Width="15" Height="20" IsBackgroundVisible="False" Margin="5,0" Click="RadButton_Click">
<ToolTipService.ToolTip>
<ToolTip Style="{StaticResource TooltipStyle}" >
<TextBlock Text="Filtre ve Rumuz bilgilerini belirlemek için tıklayın..." FontSize="13"/>
</ToolTip>
</ToolTipService.ToolTip>
<Polygon Points="1,3 6,3 3.5,7" Stroke="Gray" StrokeThickness="2" Fill="Black" VerticalAlignment="Center" />
</telerik:RadButton>
</Grid>
<TextBlock Text="{Binding FieldName}" Style="{StaticResource ListBoxItemTextBlockStyle}" Grid.Column="1" />
</Grid>
</DataTemplate>
​
<telerik:RadListBox x:Name="lbFields"
AllowDrop="True" Grid.Row="1"
ItemTemplate="{StaticResource ListBoxItemTemplate}"
ddBehaviors:CustomDragDropBehavior.IsEnabled="True" >
<telerik:RadListBox.DragDropBehavior>
<ddBehaviors:CustomDragDropBehavior />
</telerik:RadListBox.DragDropBehavior>
</telerik:RadListBox>​
public class CustomDragDropBehavior : ListBoxDragDropBehavior
{
public static bool GetIsEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}
// Using a DependencyProperty as the backing store for IsEnabled. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(ListBoxDragDropBehavior),
new PropertyMetadata(new PropertyChangedCallback(OnIsEnabledPropertyChanged)));
public static void OnIsEnabledPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
SetIsEnabled(dependencyObject, (bool)e.NewValue);
RadListBox listBox = (RadListBox)dependencyObject; ;
if (listBox.Name.Equals("lbFields")) ListBoxFields = listBox;
if (listBox.Name.Equals("lbFilters")) ListBoxFilters = listBox;
if (listBox.Name.Equals("lbRows")) ListBoxRows = listBox;
if (listBox.Name.Equals("lbColumns")) ListBoxColumns = listBox;
if (listBox.Name.Equals("lbValues")) ListBoxValues = listBox;
}
static RadListBox ListBoxFields;
static RadListBox ListBoxFilters;
static RadListBox ListBoxRows;
static RadListBox ListBoxColumns;
static RadListBox ListBoxValues;
public override void Drop(DragDropState state)
{
var insertIndex = state.InsertIndex; // -1 means that the items should be added at the end of the items source.
var allListBoxes = new List<RadListBox> { ListBoxFields, ListBoxFilters, ListBoxRows, ListBoxColumns, ListBoxValues };
var tripleListBoxes = new List<RadListBox> { ListBoxFilters, ListBoxRows, ListBoxColumns };
foreach (object item in state.DraggedItems)
{
var sourceListBox = allListBoxes
.Where(l => ((IList)l.ItemsSource).Contains(item))
.FirstOrDefault<RadListBox>();
var targetListBox = allListBoxes
.Where(l => l.ItemsSource == state.DestinationItemsSource)
.FirstOrDefault<RadListBox>();
if (sourceListBox == ListBoxFields)
{
if (insertIndex == -1) insertIndex = state.DestinationItemsSource.Count;
if (tripleListBoxes.Contains(targetListBox))
{
foreach(var lstBox in tripleListBoxes)
{
var source = (ObservableCollection<FieldX>)lstBox.ItemsSource;
source.Where(a => a.FieldID == ((FieldX)item).FieldID)
.ToList().ForEach(a => source.Remove(a));
}
state.DestinationItemsSource.Insert(insertIndex, ((FieldX)item).Clone());
}
else if (targetListBox == ListBoxValues)
{
//state.DestinationItemsSource.Insert(insertIndex, ......);
}
}
else if (tripleListBoxes.Contains(sourceListBox))
{
((IList)sourceListBox.ItemsSource).Remove(item);
if (insertIndex == -1) insertIndex = state.DestinationItemsSource.Count;
if (tripleListBoxes.Contains(targetListBox))
{
state.DestinationItemsSource.Insert(insertIndex, ((FieldX)item).Clone());
}
else if (targetListBox == ListBoxValues)
{
//state.DestinationItemsSource.Insert(insertIndex, ......);
}
}
else if (sourceListBox == ListBoxValues)
{
((IList)sourceListBox.ItemsSource).Remove(item);
if (insertIndex == -1) insertIndex = state.DestinationItemsSource.Count;
if (tripleListBoxes.Contains(targetListBox))
{
//state.DestinationItemsSource.Insert(insertIndex, ......);
}
else if (targetListBox == ListBoxValues)
{
state.DestinationItemsSource.Insert(insertIndex, ((FieldX)item).Clone());
}
//base.Drop(state);
}
}
}
public override void DragDropCompleted(DragDropState state)
{
}
}
I feel that this is not effective way that I try to go.
Best regards.
Hi Nasko,
My main purpose is viewing data from DB, not local datasource. Is it possible to use RadPivotFieldList withoutout data (at the beginning) to define which fields and with which filter values to select from database and after getting data to local binding it to LocalDataSourceProvider?
Best regardsYou could achieve the desired by you functionality. For that purpose you need first to create a ViewModel class and inside it you need to define your date provide. Please, notice that the Data Provider is not a visual element and if your are using the MVVM pattern for your application the provider won't break it. Finally you can bind RadPivotGrid's DataProvider (the same is valid also for the DataProvider of the RadPivotFieldList) to the provider in your ViewModel.
Please, check the attached sample project that demonstrates the described above approach.
We hope this will help you.
Regards,
Nasko
Telerik