2016-03-05 4 views
0

Я создаю приложение WPF с использованием MVVM Light. В нем у меня есть диалоговое окно. XAML:Кнопка OK в диалоговом окне не включена

<Window x:Class="ParserEditor.NewParserDialog" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:ParserEditor" 
     xmlns:ignore="http://www.galasoft.ch/ignore" 
     mc:Ignorable="d ignore" 
     DataContext="{Binding NewParser, Source={StaticResource Locator}}" 
     Title="New Parser..." 
     SizeToContent="Height" 
     Width="300"> 

    <Window.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Skins/MainSkin.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 

      <BitmapImage x:Key="ErrorImage" UriSource="Resources/Error.png" /> 

      <local:BooleanToVisibilityConverter x:Key="BoolToVisiblity" True="Visible" False="Collapsed" /> 

      <ControlTemplate x:Key="InputErrorTemplate"> 
       <DockPanel LastChildFill="True"> 
        <Image DockPanel.Dock="Right" 
          Height="16" 
          Margin="5" 
          Source="{StaticResource ErrorImage}" 
          ToolTip="Contains invalid data" 
          VerticalAlignment="Center" 
          Width="16" /> 
        <Border BorderBrush="Red" 
          BorderThickness="2"> 
         <AdornedElementPlaceholder /> 
        </Border> 
       </DockPanel> 
      </ControlTemplate> 

      <Style TargetType="ComboBox"> 
       <Setter Property="Margin" Value="5,4,26,4" /> 
       <Setter Property="Validation.ErrorTemplate" Value="{StaticResource InputErrorTemplate}" /> 
       <Style.Triggers> 
        <Trigger Property="Validation.HasError" Value="True"> 
         <Setter Property="ToolTip"> 
          <Setter.Value> 
           <Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" /> 
          </Setter.Value> 
         </Setter> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </ResourceDictionary> 
    </Window.Resources> 

    <Grid Name="LayoutRoot"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="10" /> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="10" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 

     <TextBlock Name="PromptLabel" 
        Grid.Column="0" 
        Grid.ColumnSpan="2" 
        Grid.Row="0" 
        Text="{Binding Path=Prompt, Mode=TwoWay}" 
        Visibility="{Binding Path=HasPrompt, Converter={StaticResource BoolToVisiblity}}"/> 

     <TextBlock Name="ParserTypeLabel" 
        Grid.Column="0" 
        Grid.Row="2" 
        Text="Parser Type:" /> 

     <ComboBox Name="ParserTypePicker" 
        Grid.Column="1" 
        Grid.Row="2" 
        ItemsSource="{Binding Path=ParserTypes}" 
        SelectedItem="{Binding Path=ParserType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 

     <Grid Name="ButtonGrid" 
       Grid.Column="0" 
       Grid.ColumnSpan="2" 
       Grid.Row="4"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 

      <Button Name="OkButton" 
        Command="{Binding CloseCommand, ValidatesOnDataErrors=True}" 
        Grid.Column="0" 
        Content="OK" 
        IsDefault="True" /> 
      <Button Name="CancelButton" 
        Grid.Column="1" 
        Content="Cancel" 
        IsCancel="True" /> 
     </Grid> 
    </Grid> 
</Window> 

объект View Model:

using System; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using GalaSoft.MvvmLight; 
using GalaSoft.MvvmLight.Command; 
using GalaSoft.MvvmLight.Messaging; 
using ParserEditor.Model; 

namespace ParserEditor.ViewModel { 

    public class NewParserViewModel : ViewModelBase, IDataErrorInfo { 

     private readonly IDataService _dataService; 

     public string ParserType { 
      get { return _ParserType; } 
      set { Set(ref _ParserType, value); } 
     } 
     private string _ParserType; 

     public ObservableCollection<string> ParserTypes { get; private set; } 

     public bool HasPrompt { 
      get { return !string.IsNullOrWhiteSpace(Prompt); } 
     } 

     public string Prompt { 
      get { return _Prompt; } 
      set { 
       Set(ref _Prompt, value); 
       RaisePropertyChanged(nameof(HasPrompt)); 
      } 
     } 
     private string _Prompt; 

     #region CloseCommand 

     public RelayCommand CloseCommand { get; private set; } 

     private bool CanCloseDialog() { 
      return ParserType == DataService.AWK_FORMAT || 
        ParserType == DataService.CSHARP_FORMAT || 
        ParserType == DataService.REGEX_FORMAT; 
     } 

     private void CloseDialog() { 
      Messenger.Default.Send(new CloseWindowMessage()); 
     } 

     #endregion 

     #region IDataErrorInfo Implementation 

     public string Error { 
      get { return this[ "ParserType" ]; } 
     } 

     public string this[ string columnName ] { 
      get { 
       switch (columnName) { 
        case "ParserType": 
         return string.IsNullOrWhiteSpace(ParserType) ? "You must choose a Parser Type" : null; 

        default: 
         return null; 
       } 
      } 
     } 

     #endregion 

     public NewParserViewModel(IDataService dataService) { 
      _dataService = dataService; 

      CloseCommand = new RelayCommand(CloseDialog, CanCloseDialog); 

      ParserTypes = new ObservableCollection<string>(); 

      ParserTypes.Add(DataService.AWK_FORMAT); 
      ParserTypes.Add(DataService.CSHARP_FORMAT); 
      ParserTypes.Add(DataService.REGEX_FORMAT); 
     } 
    } 
} 

Я поставил точку останова в CanCloseDialog method и это только получает удар один раз, при первом отображении диалогового окна. Если я выберу выбор в ComboBox после отображения диалогового окна, кнопка «ОК» не включается.

Что мне не хватает?

ответ

0

Попробуйте делегат Func, который вместо этого может вызвать CanCloseDialog. Как-то RelayCommand теряет указатель на метод без делегата. Вызов делегата в методе CanExecute реализации RelayCommand.

Что-то вроде:

CloseCommand = new RelayCommand(CloseDialog,() => {return <your condition logic>}); 
+0

Это не сработало. Не было никакой разницы в поведении. –

1

Я сделал некоторые более поиска & я, наконец, нашел ответ here. Оказывается, я должен был изменить заявление

using GalaSoft.MvvmLight.Command; 

в

GalaSoft.MvvmLight.CommandWpf; 

Делая это, все работает правильно.