Comment créer une interface utilisateur qui répond aux événements Glisser/Déposer d'un contrôle utilisateur en utilisant le modèle de commande dans WPF?Liaison de commandes à Usercontrol Glisser/Déposer
Répondre
sur le contrôle de l'utilisateur
Mettre en oeuvre une commande qui a un paramètre. J'utilise ICommand avec Josh Smiths RelayCommand, mais je l'étend pour lui donner un paramètre. (code à la fin de cette réponse)
/// <summary>
/// Gets and Sets the ICommand that manages dragging and dropping.
/// </summary>
/// <remarks>The CanExecute will be called to determin if a drop can take place, the Executed is called when a drop takes place</remarks>
public ICommand DragDropCommand {
get { return (ICommand)GetValue(DragDropCommandProperty); }
set { SetValue(DragDropCommandProperty, value); }
maintenant vous pouvez lier votre modèle de vue à cette commande.
définissez une autre propriété pour notre type de glisser entité (vous pouvez le coder en dur) mais je réutilise ce contrôle utilisateur pour différentes choses et je ne veux pas qu'un contrôle accepte le mauvais type d'entité sur une goutte.
/// <summary>
/// Gets and Sets the Name of the items we are dragging
/// </summary>
public String DragEntityType {
get { return (String)GetValue(DragEntityTypeProperty); }
set { SetValue(DragEntityTypeProperty, value); }
}
Remplacer la OnPreviewLeftMouseButtonDown
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) {
//find the item the mouse is over, i.e. the one you want to drag.
var itemToDrag = FindItem(e);
//move the selected items, using the drag entity type
DataObject data = new DataObject(this.DragEntityType, itemToDrag);
//use the helper class to initiate the drag
DragDropEffects de = DragDrop.DoDragDrop(this, data, DragDropEffects.Move);
//call the base
base.OnPreviewMouseLeftButtonDown(e);
}
lorsque vous appelez DragDrop.DoDragDrop, les méthodes suivantes seront appelées au moment approriate
Remplacer les méthodes onDragOver et OnDragDrop, et utiliser une commande pour demander si nous pouvons faire glisser et nous pouvons laisser tomber
protected override void OnDragOver(DragEventArgs e) {
//if we can accept the drop
if (this.DragDropCommand != null && this.DragDropCommand.CanExecute(e.Data)) {
// Console.WriteLine(true);
}
//otherwise
else {
e.Effects = DragDropEffects.None;
e.Handled = true;
}
base.OnDragOver(e);
}
protected override void OnDrop(DragEventArgs e) {
if (this.DragDropCommand == null) { }
//if we dont allow dropping on ourselves and we are trying to do it
//else if (this.AllowSelfDrop == false && e.Source == this) { }
else {
this.DragDropCommand.Execute(e.Data);
}
base.OnDrop(e);
}
Dans la vue Modèle
puis lorsque vous configurez votre commande dans le modèle de vue utiliser quelque chose comme ça, puis lier la commande à votre contrôle utilisateur
this.MyDropCommand = new ExtendedRelayCommand((Object o) => AddItem(o), (Object o) => { return ItemCanBeDragged(o); });
habituellement vous déplacez d'un utilisateur contrôle à un autre afin que vous définissiez une commande pour un contrôle utilisateur et un pour l'autre, chacun ayant un DragEntityType différent que vous accepteriez. Deux utilisateurs contrôlent l'un à faire glisser, un à déposer, et vice versa. Chaque contrôle utilisateur a un DragEntityType différent, ce qui vous permet de savoir de quel drag provient l'origine.
private Boolean ItemCanBeDragged(object o) {
Boolean returnValue = false;
//do they have permissions to dragt
if (this.HasPermissionToDrag) {
IDataObject data = o as IDataObject;
if (data == null) { }
//this line looks up the DragEntityType
else if (data.GetDataPresent("ItemDragEntityTypeForItemWeAreDragging")) {
returnValue = true;
}
}
return returnValue;
}
et quand nous laissons tomber
private void AddItem(object o) {
IDataObject data = o as IDataObject;
if (data == null) { }
else {
MyDataObject myData = data.GetData("ItemDragEntityTypeForItemWeAreDroppingHere") as MyDataObject ;
if (myData == null) { }
else {
//do something with the dropped data
}
}
}
Je pourrais avoir manqué quelque chose, mais cette technique me permet de demander au modèle de vue si je peux faire glisser un élément, et me permet de demander le modèle de vue si je peux drop (si le modèle de vue acceptera l'item) son bindable, et il sépare joliment le modèle view/view. Si vous avez des questions, n'hésitez pas à les poser.
étendu relais de commande, merci Josh Smith ...
/// <summary>
/// A command whose sole purpose is to
/// relay its ExtendedFunctionality to other
/// objects by invoking delegates. The
/// default return value for the CanExecute
/// method is 'true'.
/// </summary>
public class ExtendedRelayCommand : ICommand {
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public ExtendedRelayCommand(Action<Object> execute)
: this(execute, null) {
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public ExtendedRelayCommand(Action<Object> execute, Func<Object, bool> canExecute) {
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter) {
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged {
add {
if (_canExecute != null)
CommandManager.RequerySuggested += value;
}
remove {
if (_canExecute != null)
CommandManager.RequerySuggested -= value;
}
}
public void Execute(object parameter) {
_execute(parameter);
}
#endregion // ICommand Members
#region Fields
readonly Action<Object> _execute;
readonly Func<Object, bool> _canExecute;
#endregion // Fields
}
- 1. Liaison de commandes dans UserControl utilisée comme ListBox.ItemTemplate
- 2. Liaison dans WPF usercontrol
- 3. Liaison TwoWay avec UserControl
- 4. La liaison à un UserControl provoque ManagedRuntimeError
- 5. Liaison à un élément dans un UserControl
- 6. Liaison WPF à une propriété UserControl
- 7. Liaison d'un fichier XML à un UserControl
- 8. Liaison à une DependencyProperty d'un UserControl
- 9. Liaison de commandes d'image WPF
- 10. WPF: liaison et commandes
- 11. Comment accéder aux commandes sur usercontrol à partir de viewmodel
- 12. Liaison Xaml aux commandes
- 13. MVVM dans un canevas avec commandes usercontrol
- 14. UserControl Visibilité de liaison par ViewModel
- 15. WPF: Liaison d'une propriété à une coutume UserControl
- 16. WPF UserControl problème de liaison étrange
- 17. WPF Modèle de liaison dans ToggleButton UserControl
- 18. Liaison à la commande depuis l'extérieur d'un UserControl
- 19. Liaison de données à un UserControl dans WPF
- 20. Master Detail mêmes commandes de liaison View
- 21. Commandes Prism - erreur de liaison lors de la liaison à l'élément de liste?
- 22. Liaison d'une classe business simple à un WPF UserControl
- 23. Liaison du bouton Content au contenu userControl
- 24. Calendrier WPF: liaison aux commandes MVVM?
- 25. WPF - CanExecute ne se déclenche pas lorsque vous relevez des commandes à partir d'un UserControl
- 26. Propriétés de liaison de données multiples sur ASP.NET usercontrol
- 27. Liaison aux propriétés de Storyboard déclarées dans UserControl
- 28. La liaison de propriété UserControl ne fonctionne pas
- 29. WPF: Liaison de données - usercontrol ne se comporte pas
- 30. Transférer la référence WPC UserControl à un autre UserControl