在listview中使用UserControl作为DataTemplate(带有多个绑定)

时间:2012-01-21 13:01:31

标签: c# wpf user-controls

我有一个usercontrol,我在项目的几个位置使用。我使用它来显示一个字段,但不同类型的字段的布局是不同的......当我在代码中和任何模板之外使用它时工作正常,但是当我在数据模板中使用它时它不会列表显示。它唯一做的就是改变布局,但它没有显示值(如名称和描述)。

我想绑定Title,Description&等属性。键入哪些附加属性,但它们似乎不适用于datatemplate ...这些是属性:

    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    }
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register("Title", typeof(string), typeof(ucBoardField), new UIPropertyMetadata("", new PropertyChangedCallback(UpdateTitle)));

    public string Description
    {
        get { return (string)GetValue(DescriptionProperty); }
        set { SetValue(DescriptionProperty, value); }
    }
    public static readonly DependencyProperty DescriptionProperty =
        DependencyProperty.Register("Description", typeof(string), typeof(ucBoardField), new UIPropertyMetadata("", new PropertyChangedCallback(UpdateDescription)));

    public string FieldTypeDescription
    {
        get { return (string)GetValue(FieldTypeDescriptionProperty); }
        set { SetValue(FieldTypeDescriptionProperty, value); }
    }
    public static readonly DependencyProperty FieldTypeDescriptionProperty =
        DependencyProperty.Register("FieldTypeDescription", typeof(string), typeof(ucBoardField), new UIPropertyMetadata("street", new PropertyChangedCallback(UpdateFieldTypeDescription)));

这些是他们的更新方法:

    public static void UpdateTitle(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
    {
        ucBoardField bf = sender as ucBoardField;
        if (bf == null) return;
        if (bf.Field == null) bf.Field = new Field();

        bf.Field.Title = (string)eventArgs.NewValue;
        bf.lblExtraTax.Text = bf.lblStation.Text = bf.lblStreetname.Text = bf.lblUtility.Text = bf.Field.Title;
    }
    public static void UpdateDescription(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
    {
        ucBoardField bf = sender as ucBoardField;
        if (bf == null) return;
        if (bf.Field == null) bf.Field = new Field();

        bf.Field.Description = (string)eventArgs.NewValue;
        bf.lblCity.Text = bf.Field.Description;
    }
    public static void UpdateFieldTypeDescription(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
    {
        ucBoardField bf = sender as ucBoardField;
        if (bf == null) return;
        if (bf.Field == null) bf.Field = new Field();
        if (bf.Field.FieldType == null) bf.Field.FieldType = new FieldType();

        bf.Field.FieldType.Description = bf.FieldTypeDescription = (string)eventArgs.NewValue;
        bf.ShowContent(); //updates layout
    }

它们在代码中处理时工作正常,但除FieldTypeDescription之外的所有内容都在datatemplate中显示它们的结果,这就是我绑定它们的方式:

    <ListView>
        <ListView.ItemTemplate>
            <DataTemplate>
                <uc:ucBoardField 
                    Id="{Binding Path=Field.Id}"
                    FieldTypeId="{Binding Path=Field.FieldTypeId}"
                    Title="{Binding Path=Field.Title}"
                    Description="{Binding Path=Field.Description}"
                    FieldTypeDescription="{Binding Path=FieldType.Description}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

事实上,他们确实有效,但数据没有显示...... 此外,当他们的绑定被触发时,我的输出中出现错误(或警告):

System.Windows.Data Error: 40 : BindingExpression path error: 'Field' property not found on 'object' ''Field' (HashCode=64502806)'. BindingExpression:Path=Field.Title; DataItem='Field' (HashCode=64502806); target element is 'ucBoardField' (Name=''); target property is 'Title' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'Field' property not found on 'object' ''Field' (HashCode=64502806)'. BindingExpression:Path=Field.Description; DataItem='Field' (HashCode=64502806); target element is 'ucBoardField' (Name=''); target property is 'Description' (type 'String')

属性字段只是一个对象,其中包含有关要从服务器获取的字段的所有信息。 这些都在我的列表视图中:

System.Windows.Data Warning: 40 : BindingExpression path error: 'Title' property not found on 'object' ''TextBlock' (Name='lblTitle')'. BindingExpression:Path=Title; DataItem='TextBlock' (Name='lblTitle'); target element is 'TextBlock' (Name='lblTitle'); target property is 'Text' (type 'String')
System.Windows.Data Warning: 40 : BindingExpression path error: 'Description' property not found on 'object' ''TextBlock' (Name='lblDescription')'. BindingExpression:Path=Description; DataItem='TextBlock' (Name='lblDescription'); target element is 'TextBlock' (Name='lblDescription'); target property is 'Text' (type 'String')

然而它没有崩溃...... 有谁知道我可能做错了什么,为什么我会得到这些错误以及如何解决它们?我提前谢谢你了!

1 个答案:

答案 0 :(得分:0)

几分钟前我遇到了同样的问题:

您需要设置DataContext,但不能在控件中再次设置它:

<ListView>
    <ListView.ItemTemplate>
        <DataTemplate>
            <uc:ucBoardField 
                DataContext="{Binding .}"
                Id="{Binding Path=Field.Id}"
                FieldTypeId="{Binding Path=Field.FieldTypeId}"
                Title="{Binding Path=Field.Title}"
                Description="{Binding Path=Field.Description}"
                FieldTypeDescription="{Binding Path=FieldType.Description}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

但是如果您的UserControl中有以下(或类似),则无法再次使用,因为DataContext将再次被覆盖:

<UserControl ...
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             ...>