РЕДАКТИРОВАТЬ: просто снова смотрю на ваш вопрос, и я думаю, что это намного проще, чем кажется.
Единственная проблема, которую я вижу у вас, заключается в том, что отсутствие метода обработчика (и защиты) на дочерней виртуальной машине будет означать, что кнопки, которые не имеют реализации на текущей активной виртуальной машине, по-прежнему будут включены.
Стратегия по умолчанию для CM состоит в том, чтобы попытаться найти подходящее имя метода (после разбора текста действия) и, если оно не найдено, оставить кнопку в покое. Если бы вы настроили это поведение так, чтобы по умолчанию кнопки были отключены, вы могли бы легко заставить его работать, просто реализовав командные кнопки в своей оболочке, убедившись, что цель команды установлена на активный элемент:
В оболочке определите свои кнопки, убедившись, что у них есть цель, указывающая на активную дочернюю виртуальную машину.
<Button cal:Message.Attach="Command1" cal:Action.TargetWithoutContext="{Binding ActiveItem}" />
Затем просто реализуйте метод в своей дочерней виртуальной машине, как обычно.
public void Command1() { }
и опционально защита CanXX
public bool CanCommand1
{
get
{
if(someCondition) return false;
return true;
}
}
Предполагая, что вы не станете намного сложнее, чем это, это должно сработать для вас.
Я собираюсь быстро просмотреть исходный код CM и посмотреть, смогу ли я придумать что-то, что сработает для этого.
РЕДАКТИРОВАТЬ:
Хорошо, вы можете настроить функцию ActionMessage.ApplyAvailabilityEffect
, чтобы получить желаемый эффект - в вашем методе bootstrapper.Configure() (или где-то при запуске) используйте:
ActionMessage.ApplyAvailabilityEffect = context =>
{
var source = context.Source;
if (ConventionManager.HasBinding(source, UIElement.IsEnabledProperty))
{
return source.IsEnabled;
}
if (context.CanExecute != null)
{
source.IsEnabled = context.CanExecute();
}
// Added these 3 lines to get the effect you want
else if (context.Target == null)
{
source.IsEnabled = false;
}
// EDIT: Bugfix - need this to ensure the button is activated if it has a target but no guard
else
{
source.IsEnabled = true;
}
return source.IsEnabled;
};
Кажется, это работает для меня - нет цели для методов, которые нельзя было бы связать с командой, поэтому в этом случае я просто установил IsEnabled
в false. Это активирует кнопки только тогда, когда метод с соответствующей сигнатурой найден на активной дочерней виртуальной машине — очевидно, хорошо протестируйте его, прежде чем использовать :)
person
Charleh
schedule
12.03.2013