我怎样才能创建响应由usinng在WPF命令模式来拖动用户控件/删除事件的UI?命令绑定到用户控件拖/放
1
A
回答
1
在用户控制
实现具有参数的命令。我使用ICommand与Josh Smiths RelayCommand,但我扩展它给它一个参数。 (代码在这个答案的结尾)
/// <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); }
现在你可以绑定你的视图模型到这个命令。
设置另一个属性为我们的实体阻力型(你可以硬编码此),但我重复使用不同的东西,这个用户控件,我不想一个控制接受上下降了错误的实体类型。
/// <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); }
}
覆盖的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);
}
当你调用DragDrop.DoDragDrop,下面的方法将在选择恰当的时间
覆盖的OnDragOver和OnDragDrop方法调用,并使用命令问我们是否可以拖动,我们可以下降
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);
}
在视图模型
那么当你在视图模型使用像这样设置你的命令,然后将命令绑定到用户控件
this.MyDropCommand = new ExtendedRelayCommand((Object o) => AddItem(o), (Object o) => { return ItemCanBeDragged(o); });
通常你是从一个用户拖动控制到另一个,因此您将为一个用户控件设置一个命令,为另一个用户控件设置一个命令,每个命令都具有您将接受的不同DragEntityType。两个用户控制一个拖动,一个拖放,并且反之亦然。每个用户控件都有不同的DragEntityType,因此您可以知道拖动源自哪一个。
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;
}
,当我们放弃
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
}
}
}
我可能错过了一些东西,但这种技术可以让我向视图模型,如果我可以拖动一个项目,让我问视图模型,如果我能拖放(如果视图模型将接受该项目)其可绑定,并且它很好地分离视图/视图模型。如果你有任何问题随时问。
扩展接力指挥,感谢约什 - 史密斯......
/// <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. 无法传递/绑定到WPF用户控件的命令
- 2. 命令绑定到WPF中的路由事件用户控制
- 3. 绑定的MenuItems命令到用户控件的DataContext
- 4. 如何将用户控件中的item命令绑定到viewmodel命令?
- 5. 在LINQ中以NEWID命令并绑定到直放站控件
- 6. 将用户控件中的ViewModel绑定命令
- 7. 基于WPF命令/命令绑定禁用控件
- 8. WPF命令自定义用户控件
- 9. KeyDown事件绑定到用户控件
- 10. WPF的ItemsControl绑定到用户控件
- 11. 绑定到用户控件不工作
- 12. asp.net用户控件绑定
- 13. 绑定用户控件
- 14. 绑定命令到MenuItem
- 15. TextEdit_KeyDown事件绑定到一个命令
- 16. WPF MVVM:绑定命令到事件
- 17. 将用户控件绑定到自定义BusyIndicator控件
- 18. 将同一组命令附加/绑定到多个控件
- 19. SilverLight - 将命令绑定到控件模板中的按钮
- 20. C#用户控件 - 拖放和定制propertis
- 21. WPF拖放数据绑定
- 22. 无法在绑定项目控件之间拖放项目
- 23. 拖放winform控件
- 24. 使用HierarchicalDataTemplate将命令绑定到MenuItem
- 25. Silverlight:通用组件的绑定命令
- 26. 将自定义WPF控件中的事件绑定到ViewModel中的命令
- 27. 将控件绑定到用户控件属性
- 28. WPF用户控件XAML命令
- 29. WP7定制的用户控件绑定
- 30. 如何通过拖放取消拖放命令