Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当元素变为非活动状态时是否有触发的事件_C#_Wpf_Mvvm - Fatal编程技术网

C# 当元素变为非活动状态时是否有触发的事件

C# 当元素变为非活动状态时是否有触发的事件,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个与plc通信的WPF-MVVM应用程序。按下按钮时,plc中的bool变量应保持为真,如果其被释放或失去焦点或变为非活动状态,该变量应再次变为假 我用事件实现了按钮。 同时还有一个PreviewTouch和PreviewTouchDown事件,因为有多点触摸屏 ... ... 在my ViewModel中,有命令CmdSetFlag和CmdResetFlag: 公共MyViewModel:INotifyPropertyChanged { 公共MyViewModelstring页面名 {

我有一个与plc通信的WPF-MVVM应用程序。按下按钮时,plc中的bool变量应保持为真,如果其被释放或失去焦点或变为非活动状态,该变量应再次变为假

我用事件实现了按钮。 同时还有一个PreviewTouch和PreviewTouchDown事件,因为有多点触摸屏

... ... 在my ViewModel中,有命令CmdSetFlag和CmdResetFlag:

公共MyViewModel:INotifyPropertyChanged { 公共MyViewModelstring页面名 { CmdResetFlag=newactioncommandp=>MyPlc.WriteVarp.ToString,false; CmdSetFlag=new ActionCommandp=>MyPlc.WriteVarp.ToString,true; } /// ///将plc上的bool设置为false。 /// public ICommand CmdResetFlag{get;private set;} /// ///将plc上的bool设置为true。 /// 公共ICommand CmdSetFlag{get;private set;} } 因此,如果鼠标或触摸键按下,则会触发事件,并以plc变量名作为参数调用命令

然后,有一个plc客户机类向plc本身写入:

/// ///MyPlc是一个静态包装类。 ///它向实际的plc实现发送写和读命令。 /// 公共类MyPlc { 静态MyPlc { MyActualPlc=新的……可编程逻辑控制器; } /// ///实际使用的plc接口。可能存在任何类型的plc。 /// 私有IPlc MyActualPlc{get;set;} /// ///将变量写入plc。 /// ///变量的名称。 ///要写入的值。 public void WriteVarstring varName,对象值 { int myHandle=PlcClient.createVariableHandleArName; PlcClient.WriteAnymyHandle,值; PlcClient.DeleteVariableHandlemyHandle; } } 当鼠标或触摸被释放时,变量再次变为false。因此,在释放按钮之前,plc上的值保持为真


在出现类似于打开事件窗口的中断之前,这种方法可以正常工作。然后PreviewMouseUp和PreviewTouchUp事件都不会激发

我也尝试过LostFocus,但没有成功


是否有一个事件可以用来代替PreviewMouseUp或PreviewTouchUp?

在出现诸如打开事件窗口之类的中断之前工作正常,我不确定我是否理解,对不对,当控件或应用程序失去焦点时,您的事件无法工作? 当应用程序不再是前台应用程序时,可能会出现类似的情况。

可能就是解决方案

我通过使用通过行为添加的事件IsEnabledChanged和IsVisibleChanged解决了这个问题

也许这只是因为在打开一个窗口时按钮被禁用,而这个窗口会导致我在问题中描述的中断

<UserControl x:Class="..."
    ...
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ext="clr-namespace:NamespaceOfMyBehavior"
    ... >
    ...
        <Button...>
            <!-- The triggers looks like above -->
            <i:Interaction.Triggers>...</i:Interaction.Triggers>  
            <i:Interaction.Behaviors>
                <ext:PlcButtonBehavior PlcVar="PlcVar"/>
            </i:Interaction.Behaviors>
        </Button>
        ...
</UserControl>
行为类看起来像

公共类PlcButtonBehavior:行为 { 公共静态只读从属属性InvalidValueProperty= 从属属性。寄存器 无效值,类型字符串,类型按钮行为, 新建PropertyMetadatastring.Empty,d,e=> PlcButtonBehaviord.Update; 公共字符串PlcVar { 获取{返回stringGetValueInvalidValueProperty;} 集合{SetValueInvalidValueProperty,value;} } 受保护的覆盖无效连接 { 基部连接; AssociatedObject.IsEnabledChanged+=AssociatedObject_IsEnabledChanged; AssociatedObject.IsVisibleChanged+=IsVisibleChanged\u IsVisibleChanged; 使现代化 } 附加时受保护的覆盖无效 { AssociatedObject.IsEnabledChanged-=AssociatedObject_IsEnabledChanged; AssociatedObject.IsVisibleChanged-=IsVisibleChanged\u IsVisibleChanged; 碱基脱附; } 私有无效关联对象已更改 对象发送方,DependencyPropertyChangedEventArgs e { 使现代化 } 私有空间是否可见已更改\u是否可见已更改 对象发送方,DependencyPropertyChangedEventArgs e { 使现代化 } 私有无效更新 { 如果AssociatedObject是Button按钮 &&button.IsVisible &&button.i已启用 &&AssociatedObject.IsPressed { Plc.SetFlagPlcVar; } 其他的 { Plc.ResetFlagPlcVar; } } }
若要将行为中的事件设置为触发器,它将不起作用。

是否单击“执行”按钮?仅在实际释放鼠标或按enter键时执行。但触摸我不知道:问题是,某些变量应该保持为真,直到按钮被释放。例如,有一个泵应该一直运行,直到变量变为false
ed,只要按下按钮,该值将保持为真。您可以尝试将布尔viewmodel属性绑定到按钮的iPressed属性。但请注意,如果您继续按住鼠标按钮,但暂时将指针移出按钮,iPressed将变为false。从你的描述中我不清楚这是否是我想要的。这里有一个快速的XAML片段来试验这个行为:@EdPlunkett:IsPressed听起来不错,但我无法添加事件侦听器。@AndyU。显示代码和错误消息。解释你想做什么。你们把我弄丢了。我还必须得到一个事件,当一个边框变得可见时,鼠标获得另一个焦点。有一个消息边框而不是窗口。如果有消息,则会设置一个变量,使边框通过绑定可见。边框获得焦点,但按钮的LostFocus事件不会触发。