【发布时间】:2019-05-03 12:17:27
【问题描述】:
我有一个与 plc 通信的 WPF-MVVM 应用程序。当按下按钮时,PLC 中的布尔变量应保持 true,如果其释放或失去焦点或变为非活动状态,则该变量应再次变为 false。
我用事件实现了按钮。
(同时有一个PreviewTouchUp 和PreviewTouchDown 事件,因为有多点触控屏幕。)
<UserControl x:Class="..."
...
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
... >
...
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<i:InvokeCommandAction Command="{Binding CmdSetFlag}" CommandParameter="PlcVariable" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding CmdResetFlag}" CommandParameter="PlcVariable" />
</i:EventTrigger>
<!-- followed by touch events -->
</i:Interaction.Triggers>
</Button>
...
</UserControl>
在我的 ViewModel 中是命令CmdSetFlag 和CmdResetFlag:
public MyViewModel : INotifyPropertyChanged
{
public MyViewModel(string pageName)
{
CmdResetFlag = new ActionCommand((p) => MyPlc.WriteVar(p.ToString(), false));
CmdSetFlag = new ActionCommand((p) => MyPlc.WriteVar(p.ToString(), true));
}
/// <summary>
/// Sets a bool on the plc to false.
/// </summary>
public ICommand CmdResetFlag { get; private set; }
/// <summary>
/// Sets a bool on the plc to true.
/// </summary>
public ICommand CmdSetFlag { get; private set; }
}
因此,如果鼠标或触摸按下,事件将触发,并以 plc 变量名称作为参数调用命令。
然后有一个 plc 客户端类写入 plc 本身:
/// <summary>
/// MyPlc is a static wrapper class.
/// It sends write and read commands to the actual plc implementation.
/// </summary>
public class MyPlc
{
static MyPlc()
{
MyActualPlc = new ...Plc();
}
/// <summary>
/// The actual plc interface in use. There may any type of plc.
/// </summary>
private IPlc MyActualPlc { get; set; }
/// <summary>
/// Write a variable to the plc.
/// </summary>
/// <param name="varName">The name of the variable.</param>
/// <param name="value">The value to write.</param>
public void WriteVar(string varName, object value)
{
int myHandle = PlcClient.CreateVariableHandle(varName);
PlcClient.WriteAny(myHandle, value);
PlcClient.DeleteVariableHandle(myHandle);
}
}
鼠标或触摸被释放,变量再次变为假。所以 plc 上的值在按钮被释放之前保持为真。
在出现诸如在事件中打开的窗口之类的中断之前,它可以正常工作。然后PreviewMouseUp 和PreviewTouchUp 事件都不会触发。
我也试过LostFocus,但没有成功。
有没有可以用来代替PreviewMouseUp或PreviewTouchUp的事件?
【问题讨论】:
-
不会点击吗?这只在您实际释放鼠标或按下回车时执行。触摸我虽然不知道:)
-
问题是,一些变量应该保持真实,直到按钮被释放。例如,有一个泵应该运行直到变量变为 false。
-
按钮有一个属性
IsPressed,只要按钮被按下,它就保持为真。您可以尝试将布尔视图模型属性绑定到按钮的 IsPressed 属性。但请注意,如果您继续按住鼠标按钮,则 IsPressed 会转到false,但暂时将指针移出按钮。从您的描述中我不清楚是否需要这样做。这是一个快速的 XAML sn-p 来试验这种行为:<Button x:Name="Button" Content="Press" /> <CheckBox Content="It's pressed" IsChecked="{Binding IsPressed, ElementName=Button, Mode=OneWay}" /> -
@EdPlunkett:
IsPressed听起来不错,但我无法添加事件监听器。 -
@AndyU。给我看代码和错误信息。解释你想要做什么。你把我弄丢了。