TextBlock绑定显示类名而不是空字符串

Dav*_*mek 10 xaml binding microsoft-metro windows-runtime winrt-xaml

我有以下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" };
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

输出:

System.Collections.Generic.List'1[System.String]
non empty string
Run Code Online (Sandbox Code Playgroud)

我用传统的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

Wir*_*rie 5

你可以通过添加一个转换器来实际看到它是一个错误(或奇怪的故意功能)TextBlock Binding.

添加静态资源:

<Page.Resources>
    <local:NoNullsConverter x:Key="fixNulls"></local:NoNullsConverter>
</Page.Resources>
Run Code Online (Sandbox Code Playgroud)

然后更改Binding以引用Converter:

<TextBlock Text="{Binding Converter={StaticResource fixNulls}}" FontSize="25"/>
Run Code Online (Sandbox Code Playgroud)

添加此课程:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此类,您可以按预期使用Binding:

<TextBlock Text="{Binding}" FontSize="25"/>
Run Code Online (Sandbox Code Playgroud)

但是,您需要在List的声明中使用不同的类类型:

DataContext = new List<StringContext>() { "", "not empty string" };
Run Code Online (Sandbox Code Playgroud)

使用隐式转换,它"正常工作",因为它将转换String为a StringContext.是的,它会增加创建一个不必要的类的开销,但它确实有效.:)我更喜欢转换器选项.