在使用控制模板时,必须明确提供ListView的哪些组件?

时间:2015-09-28 23:19:23

标签: wpf listview controltemplate

我的问题的解决方案可能只是与WPF ListViews特别相关,但它也可能只是一个控件模板问题。我不知道。

我有以下3个属性类,在我的代码隐藏中定义了重写的ToString方法:

public class WorkListViewItem
{
    public int Id { get; set; }
    public string Namey { get; set; }
    public bool d { get; set; }

    public override string ToString()
    {
        return "ID: " + Id + "\r\nName: " + Namey + "\r\nd?:" + d.ToString();
    }
}

我在我的标记中定义了一个工作ListView,以及在所有3个类属性的窗口资源下定义的数据模板,以及在全父网格资源下定义的WorkListViewItem数组

(DTNamey也有双向绑定,文本框和附加的TextChanged事件,但这对我的问题没有影响)

数据模板:

<DataTemplate x:Key="DTNamey" DataType="{x:Type local:WorkListViewItem}">
    <TextBox Text="{Binding Path=Namey, Mode=TwoWay}" Width="65" Foreground="BlueViolet" TextChanged="TextBox_TextChanged"/>
</DataTemplate>
<DataTemplate x:Key="DTId" DataType="{x:Type local:WorkListViewItem}">
     <TextBlock Text="{Binding Path=Id}" Foreground="GreenYellow"/>
</DataTemplate>
<DataTemplate x:Key="DTd" DataType="{x:Type local:WorkListViewItem}">
    <TextBlock Text="{Binding Path=d}" Foreground="BlueViolet"/>
</DataTemplate>

数据阵列:

<x:Array Type="{x:Type local:WorkListViewItem}" x:Key="wvlis">
    <local:WorkListViewItem Id="1" Namey="Fred" d="True"/>
    <local:WorkListViewItem Id="2" Namey="Beef" d="True"/>
    <local:WorkListViewItem Id="3" Namey="Pork" d="False"/>
</x:Array>

的ListView:

<ListView x:Name="listv" ItemsSource="{StaticResource wvlis}">            
    <!--This actually works-->
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Namey" Width="80" CellTemplate="{StaticResource DTNamey}"/>
            <GridViewColumn Header="Length" Width="60" DisplayMemberBinding="{Binding Namey.Length}"/>
            <GridViewColumn Header="D?" Width="60" CellTemplate="{StaticResource DTd}"/>
        </GridView>
    </ListView.View>
</ListView>

现在这一切都完全符合我的要求: (我缺乏发布图片的声誉,但相信我,它确实如此!)

它显示数据数组中每个元素的3列和一行。 对Namey的文本框的更改将反映在第二列(长度)中,并且一切都在世界范围内。

问题:

但是,相同的ListView定义放在控件模板中时,不会显示任何项目。列显示得很好,但没有显示任何行。

窗口资源:

<!--This does not work-->
<ControlTemplate TargetType="ListView" x:Key="cmonnow">
    <ListView>
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Namey" Width="80" CellTemplate="{StaticResource DTNamey}"/>
                <GridViewColumn Header="Length" Width="60" DisplayMemberBinding="{Binding Namey.Length}"/>
                <GridViewColumn Header="D?" Width="60" CellTemplate="{StaticResource DTd}"/>
            </GridView>
        </ListView.View>
    </ListView>
</ControlTemplate>

网格内部:

<ListView x:Name="listv" ItemsSource="{StaticResource wvlis}" Template="{StaticResource cmonnow}">
</ListView>

我的努力:

我尝试在列中添加ItemsPresenter控件,这与列标题定义冲突。

我尝试在以下位置添加ItemsPresenter:

<ListView.Items>
    <ItemsPresenter/>
</ListView.Items>

我尝试将ListView的数据上下文设置为:(完全不正确,我确定)

<ListView DataContext="{Binding local:WorkListViewItem}">

我甚至尝试过定义ListView的ItemTemplate属性。

我一直在努力解决这个问题3天,并决定转向互联网寻求帮助。

所以我的问题是;使用控件模板时,需要哪些ListView属性才能显示项集合?

感谢您的时间。

马修

2015年9月29日更新

我发现将ItemsPresenter和ContentPresenter元素直接放在ListView标记下,添加了通过数据模板正确设置样式的空白项。

突破!

我发现通过将模板的ListView的ItemsSource属性绑定到提供的ItemsSource,将显示所有项目,并且所有列都已正确填充。

<ControlTemplate TargetType="ListView" x:Key="cmonnow">
    <ListView ItemsSource="{TemplateBinding ItemsSource}">
    ...
</ControlTemplate>

1 个答案:

答案 0 :(得分:0)

想出来

将其降低,似乎获取ListView控件模板以显示数据所需的唯一组件是模板ListView的ItemsSource属性。

无需手动设置ListView View属性即可查看项目。

但是,对于像我这样的自定义对象,建议覆盖ToString方法,因为这是您将看到的,没有任何进一步的模板定义。

(另一方面,必须在控制模板中定义ListView并将其TargetType属性设置为“ListView”,这有点违反直觉,但您也可以将其视为一项要求)