Что делает эта привязка, так это то, что она находит и находит элемент с именем tb
и ищет в этом элементе свойство с именем TrainDelay
. Тут же происходит сбой, потому что у TextBlock нет свойства с таким именем. TrainDelay
является свойством модели представления, а не элемента управления.
<DataTrigger
Binding="{Binding ElementName=tb, Path=TrainDelay, Converter={StaticResource TimeSpanFormatConverter}}"
Value="Delayed">
Если вы хотите вызвать «задержку» поезда, вам понадобится другой конвертер, чтобы преобразовать свойство TrainDelay
в просто перечисление. Сравнение «Задержки» с вашей отформатированной временной строкой никогда не сработает.
Этот новый конвертер может выглядеть следующим образом. Это просто упрощенная версия другой. Пока я в этом, я собираюсь переписать ваш конвертер, чтобы упростить его и удалить много лишнего кода. Избыточный код - плохая идея. Сначала это просто беспорядок. Затем кто-то приходит поддержать это год спустя, и они тратят некоторое время на подтверждение того, что эти три подвыражения действительно идентичны. В следующем году кто-то другой меняет два из них. Через год кому-то нужно внести другое изменение и по ошибке предположить, что третье было предположительно другим. Тем временем, кто-то еще скопировал и вставил весь беспорядок, и теперь у вас есть больше проблем.
public class TimeToDelayConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int.TryParse(value.ToString(), out int time);
var span = TimeSpan.FromSeconds(time);
if (string.IsNullOrWhiteSpace(value.ToString()) || span.Equals(TimeSpan.MinValue))
{
return null;
}
else
{
return TimeSpanFormatConverter.SecondsToDelay(time);
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class TimeSpanFormatConverter : IValueConverter
{
public static TrainDelay SecondsToDelay(int time)
{
if (time > 0)
{
return TrainDelay.Delayed;
}
else if (time < 0)
{
return TrainDelay.InAdvance;
}
else
{
return TrainDelay.OnTime;
}
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int.TryParse(value.ToString(), out int time);
// Don't assign this back to value. Assign it to a new variable that's properly
// typed, so you don't need to cast it.
var span = TimeSpan.FromSeconds(time);
if (string.IsNullOrWhiteSpace(value.ToString()) || span.Equals(TimeSpan.MinValue))
{
return "––:––";
}
else
{
// No need to copy and paste the same code three times.
var timeStr = ((span < TimeSpan.Zero) ? "-" : "") + span.ToString(@"mm\:ss");
return $"{SecondsToDelay(time)} {timeStr}";
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public enum TrainDelay
{
OnTime,
Delayed,
InAdvance
}
И тогда ваш триггер выглядит следующим образом. Обратите внимание, что он использует другой конвертер , чем раньше.
<DataTrigger
Binding="{Binding TrainDelay, Converter={StaticResource TimeToDelayConverter}}"
Value="Delayed">