2016-10-05 7 views
0

У меня есть TextBox, который привязан к команде, как это:Сообщите пользователю, что команда не может быть выполнена

<TextBox Text="{Binding Path=TextContent, UpdateSourceTrigger=PropertyChanged}"> 
     <TextBox.InputBindings> 
      <KeyBinding Command="{Binding Path=MyCommand}" Key="Enter" /> 
     </TextBox.InputBindings> 
</TextBox> 

Свойство TextContent является строка определяется в ViewModel. Команда MyCommand также определена в ViewModel. ViewModel не знает представление.

Команда будет вызываться всякий раз, когда TextBox имеет фокус и нажата клавиша ввода. К сожалению, если CanExecute возвращает false, пользователь не может видеть (визуально), что команда не была выполнена, потому что в TextBox нет визуальных изменений.

Я ищу совет о том, как показать пользователю, что команда не может быть выполнена после того, как он нажал кнопку ввода.

Мои идеи (и мои сомнения о них):

  • Отключение TextBox, когда CanExecute возвращается false: Это не вариант, потому что возвращаемое значение CanExecute может изменить каждый раз, когда письмо набирается/изменено (текст в TextBox влияет на результат CanExecute). Когда он отключен в первый раз, пользователь больше не может его вводить, поэтому он будет оставаться навсегда.

  • Показать окно сообщения о том, что команда не была выполнена: помните, что ViewModel не знает представление. Возможно ли открыть окно сообщений из ViewModel? Кроме того, где я должен поместить вызов для открытия окна сообщения? Не внутри CanExecute, потому что я только хочу получить окно сообщения после попадания, а не каждый раз CanExecute возвращает false. Может быть, сделать CanExecute всегда возвращать true и делать проверки внутри Execute: Если проверки в порядке, выполните команду, если нет, покажите сообщение пользователю. Но тогда, смысл иметь CanExecute пропущен полностью ...

Я хочу, чтобы MVVM, но некоторые из отделенного кода для перенаправления материала в ViewModel кажется, хорошо для меня.

+0

Что касается отображения ящиков сообщений в «View Model», вы можете использовать ориентированный на ** сервис ** подход, в котором вы можете ввести класс обслуживания окна сообщения, который может использоваться вашей моделью просмотра для отображения ящиков сообщений. Это гарантирует, что ваша модель просмотра останется верной шаблону MVVM. Я написал небольшую библиотеку, которая делает это на [GitHub] (https://github.com/mike-eason/MessageBoxAbstraction). –

ответ

1

Предлагаю следующее решение.

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

Я хочу, чтобы пользователь вводил лимит данных, который имеет тип int, double или string. Он хочет проверить, чтобы пользователь вводил правильный тип. Я использую свойство ValidateLimits, который проверяет строку MyLimits, которая в вашем случае TextContent.

Каждый раз, когда пользователь вводит что-либо в текстовом поле, ValidateLimits проверяет строку. Если это не допустимая строка в текстовом поле, тогда верните значение false, иначе верните true. Если false, выделите его с помощью DataTrigger, установив некоторые свойства в TextBox, которые в моем случае являются цветами Border и Foreground, а также ToolTip.

Также в вашем случае вы хотите вызвать метод Validate в методе CanExecute.

Если у вас уже есть функция проверки того, что команда в порядке, просто добавьте ее в привязку DataTrigger.

<TextBox Text="{Binding MyLimit1, UpdateSourceTrigger=PropertyChanged}" Margin="-6,0,-6,0"> 
    <TextBox.Style> 
    <Style TargetType="TextBox"> 
    <!-- Properties that needs to be changed with the data trigger cannot be set outside the style. Default values needs to be set inside the style --> 
    <Setter Property="ToolTip" Value="{Binding FriendlyCompareRule}"/> 
     <Style.Triggers> 
     <DataTrigger Binding="{Binding ValidateLimits}" Value="false"> 
      <Setter Property="Foreground" Value="Red"/> 
      <Setter Property="BorderBrush" Value="Red"/> 
      <Setter Property="BorderThickness" Value="2"/> 
      <Setter Property="ToolTip" Value="Cannot parse value to correct data type"/> 
     </DataTrigger> 
     </Style.Triggers> 
    </Style> 
    </TextBox.Style> 

public bool ValidateLimits 
{ 
    get 
    { 
    // Check if MyLimit1 is correct data type 
    return true/false; 
    } 
} 
0

использовать свойство bool IsCommandExecuted в вашем Command классе. Установите это свойство соответствующим образом.

Используйте ToolTip и связать его свойство IsOpen к IsCommandExecuted собственности, как это:

<TextBox ...> 
    <TextBox.ToolTip> 
     <ToolTip IsOpen="{Binding MyCommand.IsCommandExecuted}">...</ToolTip> 
    </TextBox.ToolTip> 
</TextBox> 

Это объясняет понятие, изменить его соответствующим образом.