2009-12-07 4 views

Répondre

1

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 
    } 
Questions connexes