#wpf #mvvm #command #mvvm-light
#wpf #mvvm #команда #mvvm-light
Вопрос:
У меня есть команда, которая привязывается к модели представления, включена, но не всегда выполняется. Как я могу приступить к отладке этого? Я использовал WPF Inspector, и он повторно подтверждает правильность привязки.
Подробнее: У меня есть элемент управления tab, который выполняет команду для закрытия вкладок только тогда, когда вкладка не выбрана. Когда выбрана вкладка, команда не будет выполнена.
Код довольно стандартный, и, похоже, я не могу увидеть или отладить проблемы.
Шаблонная кнопка закрытия на TabItem
<Style x:Key="ClosableStyle" TargetType="telerik:RadTabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentControl Grid.Column="0" Content="{Binding DisplayName}"/>
<telerik:RadButton Grid.Column="1" Margin="3 1 -4 0" Width="16" Height="16" Opacity="0.7" Command="{Binding Path=CloseCommand}">
<TextBlock Text="x" FontFamily="Arial Rounded MT" FontSize="12" Margin="0,-3,0,0" />
</telerik:RadButton>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Команда:
RelayCommand _closePanelCommand;
/// <summary>
/// Returns the command that, when invoked, attempts
/// to remove this workspace from the user interface.
/// </summary>
public virtual ICommand CloseCommand
{
get
{
if (_closePanelCommand == null)
{
_closePanelCommand = new RelayCommand(
() =>
{
this.OnRequestClose();
}
);
}
return _closePanelCommand;
}
}
Ответ №1:
Я также рекомендую использовать Snoop, утилиту отладки пользовательского интерфейса, которая необходима для такого рода отладки. В противном случае вы летите вслепую.
Проблема с a Button
заключается в том, что если привязка команды завершается неудачей (что происходит беззвучно), Button
остается включенной, поэтому вы не знаете, включена ли кнопка, потому что ICommand
так написано, или потому, что привязка не удалась.
Вы также можете посмотреть в своем окне вывода, которое должно сообщить вам, произошел сбой привязки, но отслеживать это немного проще, чем читать кучу текста в вашем окне вывода 🙂
Ответ №2:
Я предполагаю, в чем ваша проблема, вы пытаетесь использовать ICommand как INotifiableProperty, которое не будет работать подобным образом. Вам нужно предоставить обработчик для вашей команды в конструкторе вашей ViewModel примерно так —
this.CloseCommand= new RelayCommand(param => this.OnRequestClose(param));
И просто напишите свое свойство следующим образом —
public ICommand CloseCommand { get; set; }
Комментарии:
1. Здесь ‘param’ — это любой командный параметр, который вы хотите отправить вместе со своей командой из xaml. В случае, если вам не нужны какие-либо параметры, вы можете объявить точно так же, как вы сделали в своем свойстве. Но я буду ссылаться на использование этого синтаксиса.
2. Я думаю, что проблема была неправильно понята. OnRequestClose срабатывает, когда доходит до этой строки. Значение OnRequestClsor взято из примера MVVM Джоша Смита и является довольно распространенным.
3. Вы писали, что иногда ваша команда не выполняется, можете ли вы более конкретно рассказать о случаях, когда этого не происходит, и можете ли вы предоставить код, когда вы разобрались с ситуацией, что ваша команда не сработает, если выбран ваш tabitem. Может быть, это может как-то помочь
Ответ №3:
вы должны проверить фактический datacontext вашей кнопки (выполните поиск). я думаю, что datacontext неверен на случай, если ваша команда не будет запущена.