我正在使用Type Converter对UWP应用中绑定到TextBlocks的文本执行一些字符串操作。我使用了一个类型转换器类,我已经在许多UWP应用程序中使用,没有任何问题。但是在一个新的UWP应用程序中,我一直看到Binding值被传回的问题,并且类型转换器中没有对我传递的值进行任何更改。我一直在使用一个类型转换器,它接受参数来执行自定义操作,这不像我创建的简单的新类型转换器那样工作。奇怪的是,类型转换器在运行时工作,但在设计时被忽略。 以下是我的代码部分和XAML:
这是一个数据类,它为此repro创建样本数据以用于我的绑定:
public class Alerts_DataClass
{
public string id { get; set; }
public string severity { get; set; }
public string status { get; set; }
public string title { get; set; }
public DateTime lastEventTime { get; set; }
}
public class AlertsSampleData : Alerts_DataClass
{
public AlertsSampleData()
{
Alerts_DataClass myAlert = new Alerts_DataClass { id = "636531490526731751_2124891065", title = "Category Type XVI", severity = "Medium", lastEventTime = new DateTime(2018, 2, 02) };
this.id = myAlert.id;
this.status = myAlert.status;
this.title = myAlert.title;
this.lastEventTime = myAlert.lastEventTime;
this.severity = myAlert.severity;
}
}
这是XAML:
<Page
x:Class="NestedBindingsTester.TypeConverterTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:NestedBindingsTester"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="using:System"
mc:Ignorable="d">
<Page.Resources>
<local:StringFormatConverterWithChangeType x:Key="StringFormatConverter"/>
<local:DebugDataBindingConverter x:Key="DebugBinding"/>
<local:ValueToStringConverter x:Key="valueToStringConverter" />
<local:AlertsSampleData x:Key="data2"/>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="103*"/>
<RowDefinition Height="897*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" d:DataContext="{StaticResource data2}">
<TextBlock Text="{Binding title, ConverterParameter=lower, Converter={StaticResource StringFormatConverter}, Mode=TwoWay}" Style="{StaticResource BaseTextBlockStyle}" Margin="50,0,0,0" />
<TextBlock Text="{Binding title, Converter={StaticResource valueToStringConverter}, Mode=TwoWay}" Style="{StaticResource BaseTextBlockStyle}" Margin="50,0,0,0" />
</StackPanel>
</Grid>
</Page>
最后这里是两个Type Converter模块。第一个是简单的valueToStringConverter,我只需要传递任何String文本并将其作为小写返回:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace NestedBindingsTester
{
public sealed class ValueToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
//return value?.ToString();
string strThisTest = value.ToString().ToLower();
return strThisTest;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException("Converting from string is not supported.");
}
}
}
我使用的原始类型转换器将参数作为各种操作的开关,称为StringFormatConverter。在我的XAML示例中,我传递了'lower'参数,告诉它将字符串值转换为小写:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace NestedBindingsTester
{
public class DebugDataBindingConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
Debugger.Break();
return "This is";
////return value;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
Debugger.Break();
return "it";
////return value;
}
public object Convert(object value, Type targetType, object parameter, string language)
{
////throw new NotImplementedException();
return "Hello moto";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
/// <summary>
/// Sample usage:
/// Text="{Binding Budget, Mode=TwoWay, Converter={StaticResource StringFormatConverterWithChangeType}, ConverterParameter='\{0:C2\}'}"
/// </summary>
public class StringFormatConverterWithChangeType : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, string language)
{
// Used in UWP app
//
if (value != null)
{
// Arbitrarily remove dollar sign.
//value = value.ToString().Replace("$", "");
}
else
{
value = "**NULL**";
}
if (parameter != null)
{
string formatString = parameter.ToString();
if (!string.IsNullOrEmpty(formatString))
{
string strValue = value.ToString();
if (strValue != null && !string.IsNullOrWhiteSpace(strValue))
{
switch (formatString)
{
case "%": // Add %
return String.Format("{0}%", value);
case "mi": // Add miles
return String.Format("{0} miles", value);
case "caps": // Convert to Initial caps
return UpperCaseFirstCharacter(value.ToString());
case "lower": // Convert to Initial caps
return value.ToString().ToLower();
case "LiGa": // Convert from Liters to Gallons
{
//
// Convert kilometers to miles.
// 1 liter = 0.264172052 US gallons
//
double lConversion = 0.264172052;
double liters = System.Convert.ToDouble(strValue);
double gallons = lConversion * liters;
return String.Format("{0:N1} gallons", gallons);
}
case "TimeMath": // Compute time remaining until fully charged
{
int Minutes = System.Convert.ToInt16(value);
DateTime currentTime = DateTime.Now;
TimeSpan twoAndAHalfHours = new TimeSpan(0, Minutes, 0);
DateTime estimatedFullChargedTime = DateTime.Now.AddMinutes(Minutes);
string formattedTime = estimatedFullChargedTime.ToString("HH:mm");
return formattedTime;
}
case "UTCtoShortDate": // 02/03.2018
{
string utcDate = value.ToString(); // "2018-01-26T02:17:23.5099802Z";
DateTime dateTime;
DateTime.TryParse(utcDate, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dateTime);
Debug.WriteLine(dateTime.ToString());
string strWDATP_Date = String.Format("{0:MM.dd.yyyy}", dateTime);
return strWDATP_Date;
}
case "{0:d}": // Short date.
case "{0:D}": // Long date.
////return String.Format(culture, formatString, System.Convert.ChangeType(value, typeof(DateTime), null));
return String.Format("US", formatString, System.Convert.ChangeType(value, typeof(DateTime), null));
}
}
else
{
return String.Format("US", formatString, value);
}
}
}
return value.ToString();
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null)
{
// Arbitrarily remove dollar sign.
//value = value.ToString().Replace("$", "");
}
if (parameter != null)
{
string formatString = parameter.ToString();
if (!string.IsNullOrEmpty(formatString))
{
string strValue = value.ToString();
if (strValue != null && !string.IsNullOrWhiteSpace(strValue))
{
switch (formatString)
{
case "%": // Add %
return String.Format("{0}%", value);
case "mi": // Add miles
return String.Format("{0} miles", value);
case "caps": // Convert to Initial caps
return UpperCaseFirstCharacter(value.ToString());
case "LiGa": // Convert from Liters to Gallons
{
//
// Convert kilometers to miles.
// 1 liter = 0.264172052 US gallons
//
double lConversion = 0.264172052;
double liters = System.Convert.ToDouble(strValue);
double gallons = lConversion * liters;
return String.Format("{0:N1} gallons", gallons);
}
case "TimeMath": // Compute time remaining until fully charged
{
int Minutes = System.Convert.ToInt16(value);
DateTime currentTime = DateTime.Now;
TimeSpan twoAndAHalfHours = new TimeSpan(0, Minutes, 0);
DateTime estimatedFullChargedTime = DateTime.Now.AddMinutes(Minutes);
string formattedTime = estimatedFullChargedTime.ToString("HH:mm");
return formattedTime;
}
case "{0:d}": // Short date.
case "{0:D}": // Long date.
return String.Format(culture, formatString, System.Convert.ChangeType(value, typeof(DateTime), null));
}
}
else
{
return String.Format(culture, formatString, value);
}
}
}
return value.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public string UpperCaseFirstCharacter(string text)
{
//return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
return text.First().ToString().ToUpper() + text.Remove(0, 1).ToLower();
}
#endregion
};
}
我正在使用Visual Studio 2017并定位Windows 10 Fall Creators Update SDK(16299)。
我无法发现为什么它不再起作用,因为这些类型转换器在其他两个UWP项目中运行良好。
注意:我在TextBlocks的绑定中使用Binding,因为x:Bind不适用于设计时数据。
感谢您看一下,我一直盯着这段代码,但找不到问题。
瑞克