我的ItemsControl&amp ;;我做错了什么数据绑定?

时间:2010-06-01 19:18:53

标签: c# wpf data-binding datatemplate itemscontrol

我正在修改我的简单十六进制编辑器来练习我最近学到的关于WPF中数据绑定的知识。我不确定我在这里做错了什么。

据我了解,对于集合“backend”中的每个字节(继承自ObservableCollection),我的ItemsControl应该在资源下应用DataTemplate。此模板只是一个绑定到值转换器的文本框。所以我期待看到一行文本框,每行包含一个字节的字符串表示。当我使用这个XAML时,我得到的只是一行不可编辑的文本,据我所知,它不使用文本框。我做错了什么?

我在下面粘贴了我的XAML,删除了不相关的部分(菜单声明,架构等)。

<Window ...>
        <Window.Resources>
            <local:Backend x:Key="backend" />
            <local:ByteConverter x:Key="byteConverter" />
            <DataTemplate DataType="byte">
                <TextBox Text="{Binding Converter={StaticResource byteConverter}}" />                    
            </DataTemplate>
        </Window.Resources>
        <StackPanel>
            <ItemsControl ItemsSource="{Binding Source={StaticResource backend}}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </StackPanel>
    </Window>

1 个答案:

答案 0 :(得分:4)

当您使用默认命名空间之外的类型时,您希望绕过类型名称的默认值转换器。并且您还希望使用GetType()返回的类型名称,而不是C#编译器使用的类型名称。

首先,确保您已声明引用System命名空间的名称空间前缀,例如:

xmlns:sys="clr-namespace:System;assembly=mscorlib"

在您的DataTemplate中,使用Type标记扩展名引用该类型:

DataType="{x:Type sys:Byte}"

修改

这是一个最小的工作示例:

<Window x:Class="ByteTemplateDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:ByteTemplateDemo="clr-namespace:ByteTemplateDemo" Title="MainWindow" Height="350" Width="525">
    <DockPanel>
        <DockPanel.Resources>
            <ByteTemplateDemo:ByteConverter x:Key="ByteConverter"/>
            <DataTemplate DataType="{x:Type sys:Byte}">
                <TextBox Foreground="Red" Text="{Binding Path=., Converter={StaticResource ByteConverter}}"/>
            </DataTemplate>
        </DockPanel.Resources>
        <ItemsControl x:Name="Items" ItemsSource="{Binding}"/>
    </DockPanel>
</Window>

值转换器:

public class ByteConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Byte b = (Byte)value;
        return "b" + b.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string strValue = value as string;
        Byte result;
        if (Byte.TryParse(strValue, out result))
        {
            return result;
        }
        return DependencyProperty.UnsetValue;
    }
}

在代码隐藏中:

public MainWindow()
{
    InitializeComponent();
    ObservableCollection<byte> bytes = new ObservableCollection<byte>();
    bytes.Add(11);
    bytes.Add(12);
    bytes.Add(13);
    bytes.Add(14);
    Items.DataContext = bytes;
}

这表明模板和值转换器都被使用(因为您将看到文本框的红色值在屏幕上以“b”开头)。

请注意,双向绑定在此特定方案中不起作用,因为双向绑定需要属性名称。为了进行双向绑定,您需要创建一个类,该类公开类型为Byte的命名属性,并绑定到这些对象的可观察集合。