【问题标题】:How to databind to a ItemsControl如何将数据绑定到 ItemsControl
【发布时间】:2014-03-08 15:08:53
【问题描述】:

我有一个 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;
    }
}

【问题讨论】:

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


    【解决方案1】:

    错误消息表明绑定到属性ItemNamePriceDescription 的控件的DataContextProductListModel,而不是ProductQtyItem

    哪个模型/视图模型具有名为Collection 的属性以及Collection 的类型?我认为问题就在这里,如果它是ProductListModel 类型的话。

    更新:

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

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

    DataTemplate

    <DataTemplate x:Key="ProductItemTemplate">..</DataTemplate>
    

    然后绑定ItemsControlItemTemplate属性而不是Template属性:

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

    PS : 其实贴的信息太多了,还是不能直接复制,因为有些类的定义还是缺失的。下次尝试使用缩减的视图模型来简化场景,移除不相关的资源(样式、转换器),但要确保问题仍然存在。

    【讨论】:

    • 感谢您的回复。我意识到我没有发布正确的 XAML,遗漏了视图的模型,并且缺乏关于我正在做什么的想法的详细信息。所以我回去编辑帖子以纠正所有这些问题。
    • 检查我更新的答案。我假设ProductItemTemplateItemsControl 中每个项目的模板,而不是ItemsControl 它自身的模板。因此,我建议绑定ItemTemplate 而不是Template 属性。
    • 谢谢,这就是问题所在!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2012-09-27
    • 1970-01-01
    相关资源
    最近更新 更多