我制作了一个自定义按钮,将命令绑定到(自定义,路由)IsPressedChanged事件,以便在按下按钮和释放按钮时执行命令:

<local:CustomButton xmlns:i="http://schemas.microsoft.com/xaml/behaviors" x:Name="MyButton">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="CustomIsPressedChanged">
            <i:InvokeCommandAction Command="{Binding Path=SomeCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</local:CustomButton>

使用自定义按钮实现:

public partial class CustomButton : Button
    {
        /* Register a custom routed event using the bubble routing strategy. */
        public static readonly RoutedEvent CustomIsPressedChangedEvent = EventManager.RegisterRoutedEvent(
            name: "CustomIsPressedChanged",
            routingStrategy: RoutingStrategy.Bubble,
            handlerType: typeof(RoutedEventHandler),
            ownerType: typeof(CustomButton));

        /* Provide CLR accessors for assigning an event handler. */
        public event RoutedEventHandler CustomIsPressedChanged
        {
            add { AddHandler(CustomIsPressedChangedEvent, value); }
            remove { RemoveHandler(CustomIsPressedChangedEvent, value); }
        }

        public CustomButton() { InitializeComponent(); }

        /* Custom Event handling of the IsPressedChanged event */
        protected override void OnIsPressedChanged(System.Windows.DependencyPropertyChangedEventArgs e)
        {
            /* Call the base class OnIsPressedChanged() method so IsPressedChanged event subscribers are notified. */
            base.OnIsPressedChanged(e);

            /* Raise custom event */
            RaiseEvent(new RoutedEventArgs(routedEvent: CustomIsPressedChangedEvent));
        }
    }

这本应该是完美的.

And now comes the Problem:

当我try 将IsPressed属性的值传播到命令时,如下所示:

<i:InvokeCommandAction Command="{Binding Path=SomeCommand}"
                       CommandParameter="{Binding ElementName=MyButton, Path=IsPressed}"/>

传播的值(似乎)始终是旧值IsPressed.当我按下按钮时,调用的命令参数为false,当我松开按钮时,参数为true.But当我在事件处理程序CustomButton.OnIsPressedChanged()中判断值IsPressed时,它表示预期的新值.

My Question is:我应该如何传播IsPressed的值以获得正确的值?是否保证总是使用旧值调用该命令?在这种情况下,我可以简单地反转值,但这对我来说似乎有点可疑,我真的不想这样做,除非我知道它将始终产生正确的结果.

推荐答案

您可以将DependencyPropertyChangedEventArgs作为提升的RoutedEventArgs的参数传递:

protected override void OnIsPressedChanged(DependencyPropertyChangedEventArgs e)
{
    base.OnIsPressedChanged(e);

    // you may want to pass e.NewValue here for simplicity.
    RaiseEvent(new RoutedEventArgs(CustomIsPressedChangedEvent, e));
}

然后让InvokeCommandAction将其传递给命令:

<i:InvokeCommandAction Command="{Binding Path=SomeCommand}"
                       PassEventArgsToCommand="True" />

然后,在命令just中,您需要强制转换传递的对象以检索新值IsPressed:

SomeCommand = new ActionCommand(SomeCommandAction);

//...

private void SomeCommandAction(object o)
{
    if (o is not RoutedEventArgs routedEventArgs)
        return;

    if (routedEventArgs.OriginalSource is not DependencyPropertyChangedEventArgs eventArgs)
        return;

    if (eventArgs.NewValue is true)
        Count++;

    if (eventArgs.NewValue is false)
        Count--;

}

工作演示here.

Csharp相关问答推荐

为什么我在PuppeteerSharp中运行StealthPlugin时会出现错误?

在Dapper中使用IasyncEum重写GetAsyncEum方法

应该使用哪一个?"_counter += 1 OR互锁增量(ref_counter)"""

如何定义EFCore中的多个穿透

在.NET MAUI.NET 8中如何防止按钮点击时出现灰色反馈

TeamsBot SendActivityActivityTypes与ActivityTypes同步.键入不再起作用

异步任务导致内存泄漏

如何在C#中转换泛型包装类内部的派生类

如何比较C#中的L和ł(波兰字符)返回TRUE

如何向事件添加成员

如何在我的C#应用程序中设置带有reactjs前端的SignalR服务器?

泛型参数在.NET 8 AOT中没有匹配的批注

源代码生成器项目使用`dotnet build`编译,而不是在Visual Studio中编译?

如何在GRPC代码First服务的返回类型上使用多态性?

Content WithTargetPath实际上是有效的MSBuild项吗?

为什么C#/MSBuild会自发地为不同的项目使用不同的输出路径?

在构造函数中传递C#函数以用作EventHandler委托的订阅服务器

Foreach非常慢的C#

如何解决System.StackOverflowException:抛出System.StackOverflowException类型的异常.&# 39;生成随机代码时发生异常?

我是否以错误的方式使用了异步延迟初始化?