如何数据绑定到ItemsControl

时间:2014-02-11 01:53:16

标签: wpf silverlight data-binding silverlight-5.0 itemscontrol

我有一个SL5项目,我试图将一个集合数据绑定到ItemsControl,我不断收到错误:

BindingExpression path error: 'ItemName' property not found on 'EventViewer.Data.ViewModels.ProductListModel' 'EventViewer.Data.ViewModels.ProductListModel' (HashCode=7414170). BindingExpression: Path='ItemName' DataItem='EventViewer.Data.ViewModels.ProductListModel' (HashCode=7414170); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..
BindingExpression path error: 'Price' property not found on 'EventViewer.Data.ViewModels.ProductListModel' 'EventViewer.Data.ViewModels.ProductListModel' (HashCode=7414170). BindingExpression: Path='Price' DataItem='EventViewer.Data.ViewModels.ProductListModel' (HashCode=7414170); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..
BindingExpression path error: 'Description' property not found on 'EventViewer.Data.ViewModels.ProductListModel' 'EventViewer.Data.ViewModels.ProductListModel' (HashCode=7414170). BindingExpression: Path='Description' DataItem='EventViewer.Data.ViewModels.ProductListModel' (HashCode=7414170); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..

我在ProductQtyItem中有这些属性,并且数据绑定似乎正确设置。这就是我所拥有的:

XAML:

<sdk:ChildWindow    
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"   
    xmlns:EventViewer="clr-namespace:EventViewer" 
    xmlns:ViewModels="clr-namespace:EventViewer.Data.ViewModels"    
    xmlns:converters="clr-namespace:EventViewer.Converters"
    x:Class="EventViewer.PurchaseWindow"
    Title="Purchase"  
    HorizontalAlignment="Stretch" 
    VerticalAlignment="Stretch"
    Width="539" Height="550">
    <sdk:ChildWindow.Resources>

        <converters:BooleanVisibilityConverter x:Key="BooleanVisibilityConverter"/>
        <converters:NumericCurrencyConverter x:Key="NumericCurrencyConverter"/>

        <ControlTemplate x:Key="ProductItemTemplate" TargetType="ItemsControl">
            <Grid Margin="3">

                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" VerticalAlignment="Center" 
                           Style="{StaticResource ProductNameTextBlockStyle}"
                           Text="{Binding ItemName, Mode=OneWay}"/>

                <TextBlock Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" 
                           Style="{StaticResource ProductPriceTextBlockStyle}"
                           Text="{Binding Price, Converter={StaticResource NumericCurrencyConverter}, Mode=OneWay}" />

                <TextBlock Grid.Column="1" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" TextWrapping="Wrap" 
                           Text="{Binding Description, Mode=OneWay}"/>
            </Grid>
        </ControlTemplate>
    </sdk:ChildWindow.Resources>
    <Grid x:Name="LayoutRoot">
        <Grid.DataContext>
            <ViewModels:ProductListModel/>
        </Grid.DataContext>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Viewbox Stretch="Uniform" StretchDirection="DownOnly" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="100" 
            DataContext="{Binding ImageData}">
            <Image Source="{Binding ImagePath, Mode=OneWay}" ImageOpened="Image_ImageOpened"/>
        </Viewbox>

        <ItemsControl 
            HorizontalAlignment="Left" Margin="0,105,0,0" VerticalAlignment="Top" Width="521" Height="377"          
            Template="{StaticResource ProductItemTemplate}" 
            ItemsSource="{Binding ProductQtyItems}"/>

        <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Grid.Row="1" />
    </Grid>
</sdk:ChildWindow>

接下来的代码是我如何将ProductListModel连接到上述XAML代码的LayoutRoot.DataContext。因此,如果我理解正确,ItemsControl的绑定将绑定到ProductListModel的List ProductQtyItems。那么,模板是否将数据源设置为ProductQtyItem?我错过了什么?


以下是代码的其余部分:

这是填充数据绑定的代码:

public static void Display(FrameworkElement parent, ImageData imageData)
{
    var purchaseWindow = new PurchaseWindow();

    var productQtyItems = new List<ProductQtyItem>();
    foreach (var p in SystemSettings.GetInstance().ProductList.Collection)
    {
        int qty = 0;
        imageData.ProductListItemQty.TryGetValue(p.Id, out qty);
        productQtyItems.Add(ProductQtyItem.Create(p, qty));
    }

    purchaseWindow.LayoutRoot.DataContext = new ProductListModel
    {
        ImageData = imageData,
        ProductQtyItems = productQtyItems
    };

    purchaseWindow.Show();
}

以下是设置为LayoutRoot.Datacontext的模型:

public class ProductListModel : PropertyChangedBase
{
    private List<ProductQtyItem> _productQtyItems;
    private ImageData _imageData;

    public List<ProductQtyItem> ProductQtyItems
    {
        get { return _productQtyItems; }
        set { _productQtyItems = value; }
    }

    public ImageData ImageData
    {
        get { return _imageData; }
        set { _imageData = value; }
    }
}

最后是ProductQtyItem:

public class ProductQtyItem : PropertyChangedBase
{
    public static ProductQtyItem Create(ProductItem productItem, int qty)
    {
        return new ProductQtyItem
        {
            _productItem = productItem,
            _qty = qty,
        };
    }

    private ProductItem _productItem;
    private int _qty;

    public int Id { get { return _productItem.Id; } }
    public int SortOrder { get { return _productItem.SortOrder; } }
    public string ItemName { get { return _productItem.ItemName; } }
    public string Description { get { return _productItem.Description; } }
    public double Price { get { return _productItem.Price; } }
    public bool IsQtyEnabled { get { return _productItem.IsQtyEnabled; } }

    public int Qty
    {
        get { return _qty; }
        set
        {
            if (value != _qty)
            {
                _qty = value;
                NotifyPropertyChanged("Qty");
            }
        }
    }

    public override bool Equals(object obj)
    {
        var other = obj as ProductQtyItem;

        if (other == null)
            return false;

        return Id == other.Id;
    }

    public override int GetHashCode()
    {
        return Id;
    }
}

1 个答案:

答案 0 :(得分:1)

错误消息表明绑定到属性DataContextItemNamePrice的{​​{1}}个控件是Description而不是ProductListModel

哪个模型/ viewmodel具有名为ProductQtyItem的属性以及Collection的类型?我认为问题出在这里,如果它是Collection类型。

更新:

响应您的更新,尝试从ProductListModel更改资源定义:

ControlTemplate

<ControlTemplate x:Key="ProductItemTemplate" TargetType="ItemsControl">..</ControlTemplate>

DataTemplate

然后绑定<DataTemplate x:Key="ProductItemTemplate">..</DataTemplate> 的{​​{1}}属性而不是ItemsControl属性:

ItemTemplate
PS:实际上发布的信息太多了,仍然无法直接重现,因为某些类定义仍然缺失。下次尝试使用简化的视图模型简化场景,删除不相关的资源(样式,转换器),但要确保问题仍然出现。