【问题标题】:System.Timers.Timer Elapsed excute command not work with RelayCommandSystem.Timers.Timer Elapsed 执行命令不适用于 RelayCommand
【发布时间】:2015-11-02 02:50:42
【问题描述】:

我正在创建一个自定义用户控件,它使用计时器来计算时间并最终在视图模型中运行命令操作。

问题

当时间过去时,它运行经过的事件,然后执行一个静态命令。

事实是当我点击刷新按钮时,它可以进入RefreshCommand_Executed(这是意料之中的)。但是,即使在 BeginInvoke 中的代码运行后,它也无法为触发的计时器超时事件进入此函数(这是意外)...

请帮忙。

代码

-CustomControl.xaml.cs

public partial class CustomControl : UserControl
{
    public static ICommand ExecuteCommand = new RoutedCommand();

    public CustomControl()
    {
        System.Timers.Timer timer = new System.Timers.Timer();
        timer.AutoReset = true;
        timer.Interval = 60000.0;
        timer.Elapsed += (sender, e) =>
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (ExecuteCommand != null)
                    {
                        ExecuteCommand.Execute(sender);
                     }
                }));
        };
        timer.Start();
    }

    private void ExecuteCommand_Executed(object sender, RoutedEventArgs e)
    {
        if (ExecuteCommand != null)
        {
            ExecuteCommand.Execute(sender);
        }
    }
}

-CustomControl.xaml

<UserControl ...skip...>
    <Grid>
        <Button x:Name="refreshButton"
                Content="Refresh"
                Click="ExecuteCommand_Executed" />
    </Grid>
</UserControl>

-MainView.xaml

<UserControl ...skip...>
    <UserControl.Resources>
        <vm:MainViewModel x:Key="ViewModel" />
    </UserControl.Resources>
    <Grid cmd:RelayCommandBinding.ViewModel="{StaticResource ViewModel}">
        <cmd:RelayCommandBinding Command="ctr:CustomControl.ExecuteCommand" CommandName="RefreshCommand" />
    </Grid>
</UserControl>

-MainViewModel.cs

public class MainViewModel : NotifyPropertyChanged
{
    private ICommand refreshCommand;
    public ICommand RefreshCommand
    {
        get { return refreshCommand; }
        set { if (value != refreshCommand) { refreshCommand = value; RaisePropertyChanged("RefreshCommand"); } }
    }

    public MainViewModel()
    {
        RefreshCommand = new RelayCommand(RefreshCommand_Executed);
    }

    void RefreshCommand_Executed(object o)
    {
        //code to run
    }
}

【问题讨论】:

  • MainViewModel 负责创建计时器并响应计时器触发不是有意义吗?
  • 我知道可以,但我的目标是创建一个用户控件...

标签: c# .net mvvm relaycommand system.timers.timer


【解决方案1】:

您的计时器可能已被垃圾回收。尝试在您的控制中保留对它的引用并检查它是否有效。

顺便说一句,您可以使用 Dispatcher Timer,避免自己使用 Dispatcher。

【讨论】:

  • 不,它不是垃圾收集,它可以进入经过。问题是视图模型中的 RefreshCommand_Executed 未运行。我尝试 DispatcherTimer 无法解决问题...
  • @user1179915 好的,所以我误解了这个问题。因此,如果我理解正确:-当您单击按钮时,将调用 ExecuteCommand_Execute,命令不为空并执行-当计时器经过时,执行 lambda,执行 BeginInvoke 操作,但永远不会调用 ExecuteCommand.Execute .正确的?顺便说一句,为什么你需要一个静态命令?你不能让它成为你控制的 DependencyProperty 吗?
  • 是的,几乎你所有的理解都是对的,除了当计时器到时,执行 lambda,执行 BeginInvoke 动作,调用 ExecuteCommand.Execute,但从不调用 RefreshCommand_Executed,鼠标点击能够。我使用静态命令是因为这是我的 XP 习惯,但如果真的需要理由,我可以使用 RelayCommandBinding 来制作任何视图模型来处理执行。 DependencyProperty 需要绑定,因此只有视图的视图模型承载此用户控件来处理。虽然我可以给 DP,但我认为静态给 DP 会解决我的问题,对吧?
  • 不确定它是否能解决问题...可能您必须更深入地调试 ExecuteCommand.Execute() 方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
相关资源
最近更新 更多