Как связать свойство IsEnabled ComboBoxItem с результатом метода CanExecute команды - PullRequest
3 голосов
/ 23 февраля 2010

У меня есть собственная реализация SplitButton, в которой содержится ComboBox с несколькими привязанными ComboBoxItems командами. Я могу просто связать свойства Name и Text команды, но не могу связать свойство IsEnabled ComboBoxItem с результатом метода CanExecute команды, потому что это метод , Есть ли какой-то синтаксис, о котором я не знаю для привязки к методам, или есть какая-то хитрость, которая поможет мне привязаться к CanExecute.

Кстати, я думал об использовании пользовательского ValueConverter, за исключением того, что я понял, что, вероятно, не получу никаких обновлений, когда CanExecute будет переоценен, так как это не свойство, а мои команды не являются бизнес-объектами. , Мне кажется, что на данный момент мне, возможно, придется создать ViewModel для команды, которая будет использоваться только в моем пользовательском элементе управления SplitButton, но это кажется мне немного за борт.

Ответы [ 4 ]

1 голос
/ 24 февраля 2010

Другое решение от ViewModel. Ниже описано, как я использовал ViewModel для решения своей проблемы. И обратите внимание, что изящный метод NotifyPropertyChanged является частью моего базового класса ViewModel.

public class RoutedUICommandViewModel : ViewModel
{
    private RoutedUICommand _command;
    private IInputElement _target;

    public string Name { get { return _command.Name; } }

    public string Text { get { return _command.Text; } }

    public bool CanExecute
    {
        get
        {
            return _command.CanExecute(null, _target);
        }
    }

    public RoutedUICommand Command { get { return _command; } }

    public RoutedUICommandViewModel(ReportCommand command, IInputElement target)
    {
        _command = command;
        _target = target;
        _command.CanExecuteChanged += _command_CanExecuteChanged;
    }

    private void _command_CanExecuteChanged(object sender, EventArgs e)
    {
        base.NotifyPropertyChanged(() => this.CanExecute);
    }
}
1 голос
/ 24 февраля 2010

Я нашел это обсуждение на форумах MSDN, где Д-р. WPF рекомендовал использовать прикрепленное поведение для решения этой конкретной проблемы. Он привел приведенный ниже пример того, как он будет использоваться.

<Grid behaviors:CommandBehaviors.EnablingCommand="{x:Static commands:testcommand.test}">  
  . . .  
</Grid> 

Хотя это решение кажется довольно хорошим, я не смог посвятить время тому, чтобы точно понять, как этот тип поведения будет реализован и что с этим связано. Если кто-то хотел бы уточнить, пожалуйста, сделайте иначе, я исправлю этот ответ с более подробной информацией, если у меня будет возможность изучить этот вариант.

1 голос
/ 23 февраля 2010

Вы можете поместить кнопку (если ее нет в шаблоне элемента управления, привязанной к ICommand) внутри ItemContainerStyle (стиль ComboBoxItem) и привязать к ней команду И добавьте Trigger для проверки Button.IsEnabled и установите это значение в ComboBoxItem. Итак, здесь мы использовали Button в качестве CommandSource, чтобы получить IsEnabled из CanExeute. Вы можете установить высоту и ширину кнопки на ноль

 <ControlTemplate....>
   <Grid ...
       <Button x:Name="dummyButton" Command="{Binding YourCommand}" ....
           ......
   </Grid>

   <ControlTemplate.Triggers>
      <Trigger SourceName="dummyButton" Property="IsEnabled" Value="False">
        <Setter Property="IsEnabled" Value="False"/>
      </Trigger>
   </ControlTemplate.Triggers>
0 голосов
/ 27 мая 2011

Я решил эту проблему в своем коде, добавив обработчик событий в ComboBox для события PreviewMouseDown. Вот обработчик:

private void comboBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            ViewModel vm = this.DataContext as ViewModel;

            if (vm != null)
            {
                if (!vm.CanChangeSelection())
                {
                    e.Handled = true;
                    vm.RespondToFailedAttemptChangeUnits();
                }
            }
        }

Это прекрасно работает для меня в том случае, если мне нужно сделать это только в одном месте. Может быть немного утомительно, если у меня будет много таких страниц.

Кроме того, хотя я следую образцу MVVM, я не пурист - я считаю, что это хорошее практическое решение, которое следует духу MVVM, если не букве.

...