Ответ 1
Просто бросил тест вместе, обе эти работы для меня:
Использование полного синтаксиса:
<TextBox Name="Threshold"
Margin="5"
Grid.Column="1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<cal:ActionMessage MethodName="ExecuteFilterView">
<cal:Parameter Value="$executionContext"/>
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
Использование синтаксиса CM (предпочитайте это как можно более читаемым)
<TextBox Name="Threshold"
Margin="5"
Grid.Column="1"
cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($executionContext)]" />
Это была тестовая VM:
public class MainWindowViewModel
{
public void ExecuteFilterView(ActionExecutionContext context)
{
// This method is hit and the context is present and correct
}
}
Можете ли вы разместить свой полный код - вы уверены, что у вас правильно настроена структура? (вы следовали примеру запуска?
Edit:
Хорошо после вашего уточнения, я могу дать вам несколько примеров того, как это сделать - я расскажу вам свои личные предпочтения и почему, но выберите тот, который вам подходит лучше всего
- Используя
ActionExecutionContext
и выставив eventargs:
cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($executionContext)]"
public void ExecuteFilterView(ActionExecutionContext context)
{
var keyArgs = context.EventArgs as KeyEventArgs;
if (keyArgs != null && keyArgs.Key == Key.Enter)
{
// Do Stuff
}
}
- Использование
EventArgs
напрямую
cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($eventArgs)]"
public void ExecuteFilterView(KeyEventArgs keyArgs)
{
if (keyArgs.Key == Key.Enter)
{
// Do Stuff
}
}
- Мой личный фейв, создающий собственную запись словаря
SpecialValues
:
В вашем методе Bootstrapper.Configure
...
MessageBinder.SpecialValues.Add("$pressedkey", (context) =>
{
// NOTE: IMPORTANT - you MUST add the dictionary key as lowercase as CM
// does a ToLower on the param string you add in the action message, in fact ideally
// all your param messages should be lowercase just in case. I don't really like this
// behaviour but that how it is!
var keyArgs = context.EventArgs as KeyEventArgs;
if (keyArgs != null)
return keyArgs.Key;
return null;
});
Ваше действие:
cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($pressedKey)]"
И код:
public void ExecuteFilterView(Key key)
{
if (key == Key.Enter)
{
// Do Stuff
}
}
Почему это мой любимый? Это означает, что ваша виртуальная машина просто получает нужное значение (большую часть времени вы не заботитесь о многих других параметрах), и вам не нужно знать, как или не использовать листинг eventargs - вы можете просто управлять по значению. Очевидно, используйте то, что лучше для вас
Также стоит отметить, что если у вас есть другие типы элементов управления, то подкласс KeyEventArgs
будет работать для них. Если они не подклассы KeyEventArgs
, но они все равно возвращают значение типа Key
, это все равно будет работать, так как вы можете просто добавить еще один приведение в делегат, если первый не удался:
например.
MessageBinder.SpecialValues.Add("$pressedkey", (context) =>
{
var keyArgs = context.EventArgs as KeyEventArgs;
if (keyArgs != null)
return keyArgs.Key;
// Ok so it wasn't KeyEventArgs... check for some other type - maybe a 3rd party implementation
var thirdPartyKeyArgs = context.EventArgs as ThirdPartyKeyArgs;
if (thirdPartyKeyArgs != null)
return thirdPartyKeyArgs.KeyProperty;
return null;
});