Я хочу изменить видимость 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 и все еще пытаюсь его понять. Заранее спасибо.
Чтобы активировать конвертер, вы должны поднять NotifyPropertyChanged() вашего IsTimeValid. Таким образом, вы можете добавить NotifyPropertyChanged(nameof(IsTimeValid)); в сеттер вашего TotalStarthh





Ваша 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
}
}
Спасибо, иногда решение так просто, ха-ха.
Я бы посоветовал вам использовать nameof(IsTimeValid). Это гарантирует, что если вы переименуете свою собственность, NotifyPropertyChanged все еще будет работать.
Перед уведомлением необходимо фактически установить для свойства новое значение. Для этого используйте свойство с резервным полем.
private bool isTimeValid;
public bool IsTimeValid
{
get { return (Totalstart > Totalend); }
set
{
if (value != isTimeValid)
{
isTimeValid = value;
NotifyPropertyChanged(nameof(IsTimeValid));
}
}
}
Однако настоятельно рекомендуется использовать Prism MVVM Framework. У него есть функция SetProperty, которая делает всю эту работу за вас в одной строке.
ваш установщик свойств IsTimeValid никогда не вызывается. по крайней мере, не в этом фрагменте кода. и есть важный NotifiyPropertyChanged, который должен произойти.