Краткое объяснение
Button.CommandProperty привязан к свойству SomeObject.SomeCommand ViewModel. Когда свойство SomeCommand SomeObject имеет значение null или все свойство SomeObject имеет значение null, эта кнопка остается активной. Как можно отключить кнопку в этих условиях?
Подробное объяснение
Я создаю приложение с использованием MVVM, которое ведет себя как браузер:
Основной view_model (который соответствует главному окну как view) имеет список Workspace view_models. Каждое рабочее пространство view_model соответствует TabPage в Windows TabControl.
Главное view_model имеет свойство CurrentWorkspace, которое соответствует активной в данный момент TabPage.
В главном окне, где находится панель инструментов с кнопками, которая использует команды, предоставляемые CurrentWorkspace. Например, доступ к перезагрузке данных рабочего пространства реализован как:
<Button Name="btReload" Content="Reload"
Command="{Binding Path=CurrentWorkspace.ReloadCommand, UpdateSourceTrigger=PropertyChanged}"/>
Я попытался выполнить задачу отключения кнопок, создав DataTriggers, но кажется, что триггеры работают только в первый раз и не более:
<Button Name="btReload" Content="Reload"
Command="{Binding Path=CurrentWorkspace.ReloadCommand, UpdateSourceTrigger=PropertyChanged}">
<Button.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CurrentWorkspace, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}">
<Setter Property="dxb:BarButtonItem.IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=CurrentPage.CurrentWorkspace, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}">
<Setter Property="dxb:BarButtonItem.IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
это выглядит действительно глупо: как MS Word с бездокументной клиентской областью и в то же время с множеством готовых к щелчку кнопок на панели инструментов (с форматированием и другими специфичными для документа функциями). Пожалуйста, помогите мне:)
P.S. При добавлении на панель инструментов кнопки с DataContext, привязанной к CurrentWorkspace, ее событие DataContextChanged срабатывает правильно при активации или добавлении или удалении вкладки рабочей области в окне. Итак, проблема где-то в DataTrigger (или в View как обычно), а не в его ViewModel (s).
UPDATE
Я загрузил пример проекта на VS2010, ссылка на архив: http://www.filefactory.com/file/b43455e/n/WhatIfCommandIsNull.rar
ниже его описание.
- TextBox привязан к свойству ViewModel.Data
- Назначение или удаление ViewModel в / из Window.DataContext можно выполнить, нажав две кнопки - btAssignViewModel и btRemoveViewModel соответственно
- ViewModel предоставляет две команды, одна из которых устанавливает ViewModel.Data в строковое значение, другая - устанавливает его в NULL
- Эти команды связаны с кнопками btSetData & btResetData через их свойства Button.Command
Как вы можете видеть, когда Window.DataContext установлен в экземпляр ViewModel, обе команды работают правильно, и & ResetDataCommand.CanExecute работает тоже (когда ViewModel.Data имеет значение NULL, ResetDataCommand.CanExecute возвращает false & кнопка btResetData отключена ). Как только Window.DataContext имеет значение null, последние две кнопки активируются (для первых двух команд команды не связаны).
Проблема состоит в том, чтобы декларативно (через триггеры) реализовать следующие четыре правила:
- Если btAssignViewModel.DataContext не равен нулю, то btAssignViewModel.IsEnabled = false, в противном случае - true.
- Если btRemoveViewModel.DataContext имеет значение null, тогда btRemoveViewModel.IsEnabled = false, в противном случае - true.
- Если ViewModel.Data имеет значение null, то btSetData.IsEnabled = true, иначе false.
- Если ViewModel.Data имеет значение null, то btResetData.IsEnabled = false, иначе true.
Я думаю, что первые два правила можно реализовать с помощью триггеров, вторые два - с помощью DataTriggers. Но они не работают, поэтому я удалил их из проекта.