Aquí hay un ejemplo de cómo lo he hecho.
XAML:
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<Grid>
<ScrollViewer>
<ListView ItemsSource="{Binding MyData}" HorizontalAlignment="Stretch" Name="listview" ScrollViewer.PanningMode="VerticalOnly">
<ListView.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"
Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"
Margin="5 2" Width="150" Height="50"
FontSize="30" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Resources>
<Style TargetType="Button">
<EventSetter Event="PreviewMouseMove" Handler="PreviewMouseMove" />
<EventSetter Event="Drop" Handler="Drop" />
<Setter Property="AllowDrop" Value="True" />
</Style>
</ListView.Resources>
</ListView>
</ScrollViewer>
</Grid>
modelo de vista:
class MyViewModel
{
public MyViewModel()
{
MyCommand = new ICommandImplementation();
}
public ObservableCollection<string> MyData
{
get
{
return new ObservableCollection<string>(new string[]{
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"
});
}
}
public ICommand MyCommand { get; private set; }
private class ICommandImplementation : ICommand
{
public bool CanExecute(object parameter) { return true; }
public event EventHandler CanExecuteChanged;
public void Execute(object parameter) { System.Windows.MessageBox.Show("Button clicked! " + (parameter ?? "").ToString()); }
}
}
Incluso TS:
private void Drop(object sender, DragEventArgs e)
{
var source = e.Data.GetData("Source") as string;
if (source != null)
{
int newIndex = listview.Items.IndexOf((sender as Button).Content);
var list = listview.ItemsSource as ObservableCollection<string>;
list.RemoveAt(list.IndexOf(source));
list.Insert(newIndex, source);
}
}
private void PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Task.Factory.StartNew(new Action(() =>
{
Thread.Sleep(500);
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var data = new DataObject();
data.SetData("Source", (sender as Button).Content);
DragDrop.DoDragDrop(sender as DependencyObject, data, DragDropEffects.Move);
e.Handled = true;
}
}), null);
}), CancellationToken.None);
}
}
El ejemplo de arriba es un poco más compleja causa cada artículo de list
es un Button
y en Button
click
que también tienen que hacer algún tipo de acción. Su caso es relativamente fácil.
Arrastrar & La caída puede ser confusa para muchos desarrolladores. Pero por debajo de los son algunos puntos clave de cómo hacerlo:
Uso PreviewMouseMove
evento para iniciar realmente un lastre y en el uso manipulador DragDrop.DoDragDrop
evento para recaudar DragDrop
relacionados eventos y Cursors
. sender
argumento es el elemento que tiene capturado el mouse actualmente en este caso UIElement
que es que se está arrastrando.
Uso DragEnter
& DragOver
evento si desea cambiar la visual del elemento sobre el cual el Mouse
está arrastrando actualmente. sender
argumento es el elemento que se ha arrastrado actualmente/que acaba de finalizó el arrastre sobre la situación.
Utilice Drop
evento para controlar el elemento caído. El argumento sender
es el elemento sobre el que ocurrió el Gota.
Utilice DataObject
objeto para pasar información entre estos eventos. SetData
método de la clase se utiliza para agregar datos en esto.Este método tiene dos argumentos, y funcionan como key-value
par. Una vez configurado, puede obtener estos datos en el siguiente evento llamado DragDrop
utilizando el método GetData
pasando el key
como argumento. (Es decir e.Data.GetData("Source")
)
Here es un puesto relativa.
Hola. Veo el enlace provisto por @ Golbin. Pero el ejemplo es sobre drogas y droping entre 2 panel. De hecho, quiero reordenar en UNO 'ItemsControl' como usted. ¿Puedes ayudarme por favor? ¿Puedes poner tu código de solución aquí? ¿O puede sugerirme alguna orientación, por favor? Gracias por adelantado. –
@ king.net ¿Todavía necesita el ejemplo relacionado con este problema? aquí hay uno relacionado con el listbox - http://stackoverflow.com/questions/36642622/rearrange-customcontrol-inside-wrappanel-in-wpf-c-sharp. Si necesita puedo intentar adaptar esto para la plantilla de datos ... – Ilan