У меня есть приложение WPF-MVVM, которое связывается с ПЛК.Пока кнопка нажата на переменную bool в 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
?