WPF拖放不';t fire CommanBinding.CanExecute
是的,我知道这听起来很奇怪,但事实并非如此,问题是为什么,以及是否有解决办法。它适用于任何情况,甚至当您点击打印屏幕或暂停键时,也可以执行触发。所以在做了一个拖放之后,为了让它启动,你必须做一些其他的事情,比如鼠标点击、聚焦、按键等等。这将触发事件,并允许执行。不管怎样,这是我的代码,我知道它很长,但它会帮助你帮助我 我在我们的大型主项目中发现了这个bug,所以我将它简化为这个小应用程序来隔离问题 XAML:WPF拖放不';t fire CommanBinding.CanExecute,wpf,drag-and-drop,Wpf,Drag And Drop,是的,我知道这听起来很奇怪,但事实并非如此,问题是为什么,以及是否有解决办法。它适用于任何情况,甚至当您点击打印屏幕或暂停键时,也可以执行触发。所以在做了一个拖放之后,为了让它启动,你必须做一些其他的事情,比如鼠标点击、聚焦、按键等等。这将触发事件,并允许执行。不管怎样,这是我的代码,我知道它很长,但它会帮助你帮助我 我在我们的大型主项目中发现了这个bug,所以我将它简化为这个小应用程序来隔离问题 XAML: 允许新的 允许保存 允许撤消 允许重做 拖动此标签。。。 …在这里切换AllowNe
允许新的
允许保存
允许撤消
允许重做
拖动此标签。。。
…在这里切换AllowNew
…在这里切换AllowSave
清除列表
C#:
使用系统;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
名称空间DragnDropCommand
{
///
///Window1.xaml的交互逻辑
///
公共部分类Window1:Window
{
private CommandControl CommandControl=new CommandControl();
私有int canExecuteCount=1;
公共窗口1()
{
初始化组件();
}
已加载私有无效窗口(对象发送器、路由目标)
{
this.DataContext=commandControl;
}
私有void NewCanExecute(对象发送方,canExecuteRouteEventArgs e)
{
if(this.commandControl==null | | listViewLog==null)
返回;
e、 CanExecute=this.commandControl.AllowNew;
listViewLog.Items.Add
(
字符串格式
(
“{0}-NewCanExecute:{1}-commandControl.AllowNew:{2}”,
canExecuteCount++,e.CanExecute,commandControl.AllowNew
)
);
}
私有void NewExecuted(对象发送方,ExecutedRoutedEventArgs e)
{
MessageBox.Show(“新执行”);
}
私有void SaveCanExecute(对象发送方,CanExecuteRoutedEventArgs e)
{
if(this.commandControl==null | | listViewLog==null)
返回;
e、 CanExecute=this.commandControl.AllowSave;
listViewLog.Items.Add
(
字符串格式
(
“{0}-SaveCanExecute:{1}-commandControl.AllowSave:{2}”,
canExecuteCount++,e.CanExecute,commandControl.AllowSave
)
);
}
私有void SaveExecuted(对象发送方,ExecutedRoutedEventArgs e)
{
MessageBox.Show(“保存已执行”);
}
私有void UndoCanExecute(对象发送方,CanExecuteRoutedEventArgs e)
{
if(this.commandControl==null | | listViewLog==null)
返回;
e、 CanExecute=this.commandControl.AllowUndo;
listViewLog.Items.Add
(
字符串格式
(
“{0}-UndoCanExecute:{1}-commandControl.AllowUndo:{2}”,
canExecuteCount++,e.CanExecute,commandControl.AllowUndo
)
);
}
私有void UndoExecuted(对象发送方,ExecutedRoutedEventArgs e)
{
MessageBox.Show(“撤销已执行”);
}
私有void RedoCanExecute(对象发送方,canexecuterouteEventArgs e)
{
if(this.commandControl==null | | listViewLog==null)
返回;
e、 CanExecute=this.commandControl.AllowRedo;
listViewLog.Items.Add
(
字符串格式
(
“{0}-RedoCanExecute:{1}-commandControl.AllowRedo:{2}”,
canExecuteCount++,e.CanExecute,commandControl.AllowRedo
)
);
}
private void RedoExecuted(对象发送方,ExecutedRoutedEventArgs e)
{
MessageBox.Show(“重做已执行”);
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
listViewLog.Items.Clear();
}
私有无效标签_MouseDown(对象发送器,MouseButtonEventArgs e)
{
标签=(标签)发送者;
如果(e.LeftButton==鼠标按钮状态。按下)
DragDrop.DoDragDrop(标签,标签,DragDropEffects.Move);
}
专用无效标签ELDROPNEW_Drop(对象发送器,DragEventArgs e)
{
this.commandControl.AllowNew=!this.commandControl.AllowNew;
}
私有无效标签ELDROPSAVE_Drop(对象发送方,DragEventArgs e)
{
this.commandControl.AllowSave=!this.commandControl.AllowSave;
}
}
公共类CommandControl:DependencyObject
{
公共场所许可
{
获取{return(bool)GetValue(AllowNewProperty);}
set{SetValue(AllowNewProperty,value);}
}
//使用DependencyProperty作为AllowNew的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性AllowneProperty=
DependencyProperty.Register(“AllowNew”、typeof(bool)、typeof(CommandControl)、新UIPropertyMetadata(false));
公共布尔允许保存
{
获取{return(bool)GetValue(AllowSaveProperty);}
set{SetValue(AllowSaveProperty,value);}
}
//使用DependencyProperty作为AllowSave的备份存储。这将启用动画、样式、绑定等。。。
公共静态区域
<Window x:Class="DragNDropCommands.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="485" SizeToContent="Width" Loaded="Window_Loaded">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.New" CanExecute="NewCanExecute" Executed="NewExecuted" />
<CommandBinding Command="ApplicationCommands.Save" CanExecute="SaveCanExecute" Executed="SaveExecuted" />
<CommandBinding Command="ApplicationCommands.Undo" CanExecute="UndoCanExecute" Executed="UndoExecuted" />
<CommandBinding Command="ApplicationCommands.Redo" CanExecute="RedoCanExecute" Executed="RedoExecuted" />
</Window.CommandBindings>
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Command="ApplicationCommands.New" Grid.Row="0" Grid.Column="0" FontWeight="Bold" Content="New" Width="80" Margin="8"></Button>
<Button Command="ApplicationCommands.Save" Grid.Row="0" Grid.Column="1" FontWeight="Bold" Content="Save" Width="80" Margin="8"></Button>
<Button Command="ApplicationCommands.Undo" Grid.Row="0" Grid.Column="2" FontWeight="Bold" Content="Undo" Width="80" Margin="8"></Button>
<Button Command="ApplicationCommands.Redo" Grid.Row="0" Grid.Column="3" FontWeight="Bold" Content="Redo" Width="80" Margin="8"></Button>
<CheckBox Grid.Row="1" Grid.Column="0" Margin="8" IsChecked="{Binding Path=AllowNew, Mode=TwoWay}">Allow New</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="1" Margin="8" IsChecked="{Binding Path=AllowSave}">Allow Save</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="2" Margin="8" IsChecked="{Binding Path=AllowUndo}">Allow Undo</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="3" Margin="8" IsChecked="{Binding Path=AllowRedo}">Allow Redo</CheckBox>
<Label x:Name="labelDrag" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" BorderBrush="Black" BorderThickness="1" MouseDown="Label_MouseDown"
Background="LightBlue" HorizontalContentAlignment="Center" Margin="8">Drag this label...</Label>
<Label x:Name="labelDropNew" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" BorderBrush="Black" BorderThickness="1" Drop="labelDropNew_Drop"
Background="LightGray" HorizontalContentAlignment="Center" Margin="8" AllowDrop="True">...here to toggle AllowNew</Label>
<Label x:Name="labelDropSave" Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" BorderBrush="Black" BorderThickness="1" Drop="labelDropSave_Drop"
Background="LightGray" HorizontalContentAlignment="Center" Margin="8" AllowDrop="True">...here to toggle AllowSave</Label>
<ListBox x:Name="listViewLog" Grid.Row="4" Grid.ColumnSpan="4" Margin="8" Width="500">
</ListBox>
<Button Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2" Margin="8" Click="Button_Click">Clear list</Button>
</Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace DragNDropCommands
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private CommandControl commandControl = new CommandControl();
private int canExecuteCount = 1;
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = commandControl;
}
private void NewCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowNew;
listViewLog.Items.Add
(
String.Format
(
"{0} - NewCanExecute: {1} - commandControl.AllowNew: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowNew
)
);
}
private void NewExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("New executed");
}
private void SaveCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowSave;
listViewLog.Items.Add
(
String.Format
(
"{0} - SaveCanExecute: {1} - commandControl.AllowSave: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowSave
)
);
}
private void SaveExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Save executed");
}
private void UndoCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowUndo;
listViewLog.Items.Add
(
String.Format
(
"{0} - UndoCanExecute: {1} - commandControl.AllowUndo: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowUndo
)
);
}
private void UndoExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Undo executed");
}
private void RedoCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowRedo;
listViewLog.Items.Add
(
String.Format
(
"{0} - RedoCanExecute: {1} - commandControl.AllowRedo: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowRedo
)
);
}
private void RedoExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Redo executed");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
listViewLog.Items.Clear();
}
private void Label_MouseDown(object sender, MouseButtonEventArgs e)
{
Label label = (Label)sender;
if(e.LeftButton == MouseButtonState.Pressed)
DragDrop.DoDragDrop(label, label, DragDropEffects.Move);
}
private void labelDropNew_Drop(object sender, DragEventArgs e)
{
this.commandControl.AllowNew = !this.commandControl.AllowNew;
}
private void labelDropSave_Drop(object sender, DragEventArgs e)
{
this.commandControl.AllowSave = !this.commandControl.AllowSave;
}
}
public class CommandControl : DependencyObject
{
public bool AllowNew
{
get { return (bool)GetValue(AllowNewProperty); }
set { SetValue(AllowNewProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowNew. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowNewProperty =
DependencyProperty.Register("AllowNew", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
public bool AllowSave
{
get { return (bool)GetValue(AllowSaveProperty); }
set { SetValue(AllowSaveProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowSave. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowSaveProperty =
DependencyProperty.Register("AllowSave", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
public bool AllowUndo
{
get { return (bool)GetValue(AllowUndoProperty); }
set { SetValue(AllowUndoProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowUndo. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowUndoProperty =
DependencyProperty.Register("AllowUndo", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
public bool AllowRedo
{
get { return (bool)GetValue(AllowRedoProperty); }
set { SetValue(AllowRedoProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowRedo. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowRedoProperty =
DependencyProperty.Register("AllowRedo", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
}
}