【问题标题】:WPF Window custom event creating and binding to ICommandWPF Window 自定义事件创建和绑定到 ICommand
【发布时间】:2021-12-24 20:29:58
【问题描述】:

这是 WPF/MVVM 应用程序。 MainWindow.xaml.cs 后面的代码中有一些代码应该生成自定义事件,并且需要将此事件的事实(可能带有 args)报告给视图模型类(MainWindowViewModel.cs)。

例如。我在 partial class MainWindow 中声明了 RoutedEvent TimerEvent,但由于此事件在 xaml 代码中不可用,我无法绑定到视图模型命令。错误:定时器无法识别或无法访问。

如何解决这个问题?谢谢!

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var timer = new Timer();
            timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            timer.Interval = 5000;
            timer.Enabled = true;
        }

        private void OnTimedEvent(object sender, ElapsedEventArgs e)
        {
            RaiseTimerEvent();
        }

        // Create a custom routed event
        public static readonly RoutedEvent TimerEvent = EventManager.RegisterRoutedEvent(
            "Timer", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MainWindow));

        // Provide CLR accessors for the event
        public event RoutedEventHandler Timer
        {
            add => AddHandler(TimerEvent, value);
            remove => RemoveHandler(TimerEvent, value);
        }
        
        void RaiseTimerEvent()
        {
            var newEventArgs = new RoutedEventArgs(MainWindow.TimerEvent);
            RaiseEvent(newEventArgs);
        }
    }
<Window x:Class="CustomWindowEvent.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CustomWindowEvent"
        Title="MainWindow" Height="250" Width="400"
        Timer="{Binding TimerCommand}">   // THIS PRODUCE ERROR Timer is not recognized or is not accessible.

    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>

    <Grid>
        <StackPanel>
            <TextBlock Text="{Binding Title}"/>
            <Button Width="75"
                    Height="24"
                    Content="Run"
                    Command="{Binding RunCommand}"/>
        </StackPanel>
    </Grid>
</Window>

【问题讨论】:

  • 您为什么要尝试将事件绑定到命令...?这不是它的工作原理。
  • 如何向 ViewModel 报告部分类 MainWindow 中的任何自定义事件?
  • 请参考我的回答。
  • 定时器应该直接在视图模型类中实现。
  • @BionicCode,这只是举例。在实际代码中有一些使用窗口句柄的算法。

标签: c# wpf events mvvm data-binding


【解决方案1】:

您不能像这样将ICommand 属性绑定到事件。

当您的窗口发出命令时,您可能会以编程方式调用该命令:

void RaiseTimerEvent()
{
    var newEventArgs = new RoutedEventArgs(MainWindow.TimerEvent);
    RaiseEvent(newEventArgs);

    var vm = this.DataContext as MainWindowViewModel;
    if (vm != null)
        vm.TimerCommand.Execute(null);
}

另一种选择是使用Microsoft.Xaml.Behaviors.Wpf 包中的EventTriggerInvokeCommandAction 来使用XAML 调用命令:

<Window .. xmlns:i="http://schemas.microsoft.com/xaml/behaviors">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Timer" >
            <i:InvokeCommandAction Command="{Binding TimerCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Window>

更多信息请参考this blog post

【讨论】:

  • 感谢您的回答和您的博客!
猜你喜欢
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 2015-04-02
  • 2013-11-05
  • 2015-11-13
相关资源
最近更新 更多