我有以下Windows RT应用程序。我将一个字符串列表绑定到TextBlocks的ItemsControl。这将显示空字符串“System.Collections.Generic.List'1 [System.String]”而不是空字符串。我希望它显示一个空字符串而不是DataContext的类型。
代码背后的代码:public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext = new List<string>() { "", "not empty string" };
}
}
XAML:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="25"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
输出:
System.Collections.Generic.List'1[System.String]
non empty string
我用传统的wpf做了同样的例子,它正确地显示了空字符串。
修改 这输出同样的东西。
代码背后的代码:public class Model
{
private readonly List<string> items = new List<string>() { "", "non empty string" };
public List<string> Items
{
get { return items; }
}
}
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext = new Model();
}
}
XAML:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ItemsControl ItemsSource="{Binding Path=Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="25"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
答案 0 :(得分:5)
通过向TextBlock
Binding
添加转换器,您实际上可以看到这是一个错误(或奇怪的故意功能)。
添加静态资源:
<Page.Resources>
<local:NoNullsConverter x:Key="fixNulls"></local:NoNullsConverter>
</Page.Resources>
然后更改Binding以引用Converter:
<TextBlock Text="{Binding Converter={StaticResource fixNulls}}" FontSize="25"/>
添加此课程:
public class NoNullsConverter : IValueConverter
{
// This converts the value object to the string to display.
public object Convert(object value, Type targetType,
object parameter, string language)
{
return value is string ? value : "";
}
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException();
}
}
如果在return
语句上放置断点,您将看到实际传递的第一个值是整个列表。是的,出乎意料。但是,如果你使用这个转换器,它会处理这种奇怪的现象并返回一个更逻辑的空字符串。
或者,你可以做更多有趣的并创建一个简单的包装类:
public class StringContext
{
public string Value { get; set; }
public static implicit operator StringContext(string value)
{
return new StringContext() { Value = value };
}
public override string ToString()
{
return Value;
}
}
使用此类,您可以按预期使用Binding:
<TextBlock Text="{Binding}" FontSize="25"/>
但是,您需要在List的声明中使用不同的类类型:
DataContext = new List<StringContext>() { "", "not empty string" };
使用隐式强制转换,它“正常工作”,因为它将String
转换为StringContext
。是的,它会增加创建一个不必要的类的开销,但它确实有效。 :)我更喜欢转换器选项。
答案 1 :(得分:1)
我真的无法解释原因,但是当您直接设置ItemsSource
属性时,它会按预期工作:
<ItemsControl x:Name="itemsControl">
...
</ItemsControl>
public MainPage()
{
this.InitializeComponent();
itemsControl.ItemsSource = new List<string>() { "", "not empty string" };
}
我也试过这个:
<ItemsControl ItemsSource="{Binding Items}">
...
</ItemsControl>
public MainPage()
{
this.InitializeComponent();
Items = new List<string>() { "", "not empty string" };
DataContext = this;
}
public IEnumerable Items { get; set; }
但它会导致显示
<强> TextBlockBindingTest.MainPage 强>
非空字符串
显然,当项绑定计算为 null或为空时,它将回退到继承的DataContext。我猜这是WinRT中的一个错误。
或者,您也可以设置MainPage类的Name
属性并写下这样的绑定:
<Page ... x:Name="mainPage">
...
<ItemsControl ItemsSource="{Binding Items, ElementName=mainPage}">
...
</ItemsControl>
并且没有设置DataContext:
public MainPage()
{
this.InitializeComponent();
Items = new List<string>() { "", "not empty string" };
}
答案 2 :(得分:0)
或尝试设置绑定代码:
//list is ItemsControl
var bin = new Binding();
var mylist = new List<string>(){"","not empty string"};
bin.Source = mylist;
list.SetBinding(ItemsControl.ItemsSourceProperty,bin);
这对我有用。
答案 3 :(得分:0)
实际上,我偶然发现了一个更简单的解决方案。毫无疑问,这是一个错误。 WPF中的相同代码给出了预期的结果。错误的来源是TargetNullValue属性,它不能正确解释空字符串。要解决这个问题,您可以使用上面建议的IValueConverter(转换器解决方案根据我的经验存在性能问题)或使用:
<TextBlock Text="{Binding TargetNullValue=' '}" FontSize="25"/>