Преобразователь видимости в MVVM не обновляется

Я хочу изменить видимость Grid в зависимости от того, больше ли значение одного TextBoxes, чем другого TextBoxes. Я использую MVVM и имею следующий код:

XAML

<UserControl.Resources>
    <BooleanToVisibilityConverter x:Key = "BoolToVis"/>
</UserControl.Resources>

<Grid x:Name = "TimeError" Visibility = "{Binding Path=IsTimeValid, Converter = {StaticResource BoolToVis}}">
    <TextBlock Text = "Incorrect value"/>
</Grid>

<TextBox x:Name = "TotalStarthh" MaxLength = "2" FontSize = "16" Width = "28" Text = "{Binding TotalStarthh}"/>
<more TextBoxes/>

В ViewModel я анализирую textBoxes до целочисленного значения и вычисляю общее время.

private string _TotalStarthh;
public string TotalStarthh
{
    get { return _TotalStarthh; }
    set { _TotalStarthh = value; NotifyPropertyChanged(); }
}
//The same for the other TextBoxes.

public int Totalstart()
{
    int.TryParse(TotalStarthh, out int TShh);
    int.TryParse(TotalStartmm, out int TSmm);
    int.TryParse(TotalStartss, out int TSss);
    //calculating hours:mins:sec to total seconds
    //This can be over 24 hours so datetime is not used
    int Totalstart = TShh * 3600 + TSmm * 60 + TSss;
    return Totalstart;
}

public int Totalend()
{
    int.TryParse(TotalEndhh, out int TEhh);
    int.TryParse(TotalEndmm, out int TEmm);
    int.TryParse(TotalEndss, out int TEss);
    //calculating hours:mins:sec to total seconds
    //This can be over 24 hours so datetime is not used
    int Totalend = TEhh * 3600 + TEmm * 60 + TEss;
    return Totalend;
}

// validate that start time is lower than end time.
public bool IsTimeValid
{
    get { return (Totalstart > Totalend); }
    set { NotifyPropertyChanged(); }
}

Но это не обновляет видимость Grid. Я делаю NotifyPropertyChanged неправильно? Я новичок в mvvm и все еще пытаюсь его понять. Заранее спасибо.

ваш установщик свойств IsTimeValid никогда не вызывается. по крайней мере, не в этом фрагменте кода. и есть важный NotifiyPropertyChanged, который должен произойти.

Jurica Smircic 30.04.2019 15:28

Чтобы активировать конвертер, вы должны поднять NotifyPropertyChanged() вашего IsTimeValid. Таким образом, вы можете добавить NotifyPropertyChanged(nameof(IsTimeValid)); в сеттер вашего TotalStarthh

Martin Backasch 30.04.2019 15:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

Или вы можете уведомлять пользовательский интерфейс об изменении IsTimeValid каждый раз, когда вы меняете два используемых свойства. Чтобы объяснить, как это сделать, нам нужно знать, как на самом деле выглядит ваш NotifyPropertyChanged.

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

public string TotalStarthh
{
    get { return _TotalStarthh; }
    set 
    {
         _TotalStarthh = value;
         NotifyPropertyChanged(); // notifies the UI this property has changed
         NotifyPropertyChanged("IsTimeValid"); // notifies the UI IsTimeValid has changed 
    }
}

Спасибо, иногда решение так просто, ха-ха.

K.Luth 30.04.2019 16:44

Я бы посоветовал вам использовать nameof(IsTimeValid). Это гарантирует, что если вы переименуете свою собственность, NotifyPropertyChanged все еще будет работать.

SimonG 30.04.2019 17:04

Перед уведомлением необходимо фактически установить для свойства новое значение. Для этого используйте свойство с резервным полем.

private bool isTimeValid;
public bool IsTimeValid
{ 
  get { return (Totalstart > Totalend); }
  set
  {
    if (value != isTimeValid)
      {
        isTimeValid = value;
        NotifyPropertyChanged(nameof(IsTimeValid));
      }
   }
 }

Однако настоятельно рекомендуется использовать Prism MVVM Framework. У него есть функция SetProperty, которая делает всю эту работу за вас в одной строке.

Другие вопросы по теме