我怎樣才能創建響應由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. 如何通過拖放取消拖放命令