gpt4 book ai didi

WPF 拖放不会触发 Command Binding.CanExecute

转载 作者:行者123 更新时间:2023-12-04 14:28:06 24 4
gpt4 key购买 nike

是的,我知道这听起来很奇怪,但事实并非如此,问题是为什么,以及是否有变通办法。它适用于所有内容,即使您按下 PrintScreen 或 Pause 键,CanExecute 也会触发。所以在拖放之后,为了让它触发,你必须做一些其他的“事情”,比如鼠标点击、聚焦、击键等等。这将使事件触发,并允许 Execute 发生。无论如何,这是我的代码,我知道它很长,但它会帮助你帮助我。

我在我们的大型主项目中发现了这个错误,所以我将它简化为这个小应用程序以隔离问题。

XAML:

<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>

C#:

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));
}
}

您应该能够只复制粘贴并进行一些名称更改(文件、命名空间)以使其运行。我真的很想得到你的帮助,因为这让我抓狂,现在我终于找到了这个错误的原因,我不知道该怎么办。

非常感谢任何建议。

提前致谢。

最佳答案

只是一个简单的建议:

您可以在拖放事件处理程序中使用 CommandManager.InvalidateRequerySuggested() 来强制重新执行 CanExecute()。 ( Link )

关于WPF 拖放不会触发 Command Binding.CanExecute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/896114/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com