C # / MVVM: включить / отключить кнопки на основе свойства другого элемента управления - PullRequest
0 голосов
/ 07 октября 2010

Скажем, у меня есть элемент управления табуляции, который отображает данные различных типов, например EditorTabViewModel, PreviewTabViewModel, оба наследуются от TabViewModel.Реализация аналогична учебнику на MSDN

. Я хочу включить кнопки в зависимости от активной вкладки, будь то EditorTabViewModel или PreviewTabViewModel.Как мне этого добиться?

ОБНОВЛЕНИЕ

public ICommand EditorCommand
{
    get
    {
        if (_editorCommand == null) {
            _editorCommand = new RelayCommand(() =>
            {
                MessageBox.Show("Editor");
            }, () =>
            {
                var enabled = true;
                var viewSource = CollectionViewSource.GetDefaultView(Tabs);
                viewSource.CurrentChanged += (o, e) =>
                {
                    if (viewSource.CurrentItem is EditorTabViewModel)
                    {
                        enabled = false;
                    }
                };
                return enabled;
            });
        }
        return _editorCommand;
    }
}

ОБНОВЛЕНИЕ 2

public ICommand PreviewCommand
{
    get
    {
        if (_previewCommand == null) {
            _previewCommand = new RelayCommand(() =>
            {
                MessageBox.Show("Preview");
            }, () =>
            {
                var viewSource = CollectionViewSource.GetDefaultView(Tabs);
                var enabled = viewSource.CurrentItem is EditorTabViewModel;
                viewSource.CurrentChanged += (o, e) =>
                {
                    CommandManager.InvalidateRequerySuggested();
                };
                return enabled;
            });
        }
        return _previewCommand;
    }
}

Ответы [ 4 ]

3 голосов
/ 07 октября 2010

Я бы посоветовал вам создать ICommand реализацию, которая работает на ICollectionView, которая содержит 2 элемента управления с вкладками.Затем команда может отреагировать на событие CurrentChanged из представления сбора, чтобы определить, следует ли его включить, и вызвать событие CanExecuteChanged, чтобы указать на изменение.

class MyCommand : ICommand
{
    private bool _isEnabled = true;

    public MyCommand(MyTopLevelViewModel viewModel)
    {
        var viewSource = CollectionViewSource.GetDefaultView(viewModel.Tabs);
        viewSource.CurrentChanged += (o,e) =>
            {
                _isEnabled = (viewSource.CurrentItem is EditorTabViewModel); //or however you want to decide

                if (this.CanExecuteChanged != null) 
                     this.CanExecuteChanged(this, EventArgs.Empty);

            };
    }

    public void Execute(object parameter) { /*...*/ }

    public bool CanExecute(object parameter) { return _isEnabled; }

    public event EventHandler CanExecuteChanged;
}

Примечание.необходимо установить свойство IsSyncronizedWithCurrentItem на вкладке:

<TabControl IsSynchronizedWithCurrentItem="True" />
0 голосов
/ 07 октября 2010

Может быть больше в соответствии с MVVM, чтобы сделать 2 представления (шаблоны данных). Просто сделайте их как дженерики в ресурсах управления.

<TabControl>
<TabControl.Resources>
    <DataTemplate DataType="EditorTabViewModel">
         <Button Content="Enabled for Editor only" IsEnabled=True Command=SomeCommand />
         <Button Content="Enabled for Preview only" IsEnabled=False Command=SomeCommand />
    </DataTemplate/>
    <DataTemplate DataType="PreviewTabViewModel">
        <Button Content="Enabled for Editor only" IsEnabled=False Command=SomeCommand />
        <Button Content="Enabled for Preview only" IsEnabled=True Command=SomeCommand />
    </DataTemplate>
</TabControl.Resources>
<TabControl.ItemTemplate>
    <DataTemplate DataType="TabViewModel">
        <TextBlock Text="{Binding SomeValueToShowAsHeader}" />
    </DataTemplate>
</TabControl.ItemTemplate>
</TabControl>

Итак, все, что происходит, - все вкладки имеют одинаковый заголовок вкладки, потому что шаблон элемента явно определен. Но поскольку ContentTemplates не определены явно, когда элемент управления ищет шаблон для содержимого, он предоставит ему шаблон по умолчанию для домена. Поскольку мы определяем 2 шаблона по умолчанию, один для EditorTabViewModel и один для PreviewTabViewModel, когда он сталкивается с одним из них, он назначит его этому шаблону данных. Это должно привести к отображению двух разных дисплеев в коллекции вкладок. Я не пробовал полностью с помощью view view модели с вкладками, поэтому дайте мне знать, если он не работает, как ожидалось.

0 голосов
/ 07 октября 2010

Добавьте свойство «только для чтения» в вашей модели представления окна, которое представляет видимость вкладок:

public bool EditorTabVisible{
    get{
        return GetActiveWorkspace() is EditorTabViewModel;
    }
}

Вам также нужно иметь событие, которое срабатывает при изменении активной вкладки и добавлении этого события.обработчик:

OnPropertyChanged("EditorTabVisible");

Затем вы можете привязать свойство IsEnabled кнопки к этому свойству.

Я не знаю, есть ли лучший способ сделать это, но это работает для меня.

0 голосов
/ 07 октября 2010

Я бы использовал ValueConverter и передал бы Active в качестве значения

Вы можете конвертировать из чего угодно во что угодно. Переход в активную форму может определить тип и, следовательно, вернуть true / false для привязки к свойству кнопок enabled.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...