使用控件模板时必须明确提供 ListView 的哪些组件?
Which components of a ListView have to be explicitly provided when utilising Control Templates?
我的问题的解决方案可能只是与 WPF ListViews 具体相关,但它也可能只是一般的控件模板问题。我不知道。
我有以下 3 个 属性 class,在我的代码隐藏中定义了覆盖的 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,以及在 window 的所有 3 个 class 属性的资源下定义的数据模板,以及在 class 下定义的一个 WorkListViewItem 数组=71=]网格的资源。
(DTNamey 还具有 two-way 绑定、文本框和附加的 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 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>
现在这一切都完全符合我的要求:
(我缺乏 post 图片的声誉,但相信我,它确实如此!)
它显示数据数组中每个元素的 3 列和一行。
Namey 文本框的更改反映在第二列(长度)中,一切都很好。
问题:
但是,相同的 ListView 定义在放置在控件模板中时不显示任何项目。列显示得很好,但没有显示行。
Window 资源:
<!--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 控件,这与列 header 定义冲突。
我尝试在以下位置添加 ItemsPresenter:
<ListView.Items>
<ItemsPresenter/>
</ListView.Items>
我试过将 ListView 的数据上下文设置为:(完全不正确,我敢肯定)
<ListView DataContext="{Binding local:WorkListViewItem}">
我什至尝试过定义 ListView 的 ItemTemplate 属性。
我已经研究了 3 天,并决定求助于互联网。
所以我的问题是;使用控件模板时需要哪些 ListView 属性才能显示项目 collection?
感谢您的宝贵时间。
马修
2015 年 9 月 29 日更新
我发现将 ItemsPresenter 和 ContentPresenter 元素直接放在 ListView 标签下,会添加通过数据模板正确设置样式的空白项。
突破!
我发现通过将模板的 ListView 的 ItemsSource 属性 绑定到提供的 ItemsSource,所有项目都会显示,所有列都会正确填充。
<ControlTemplate TargetType="ListView" x:Key="cmonnow">
<ListView ItemsSource="{TemplateBinding ItemsSource}">
...
</ControlTemplate>
想通了
归根结底,似乎获得 ListView 控件模板以显示数据所需的唯一组件是模板 ListView 的 ItemsSource 属性。
无需手动设置 ListView 视图 属性 即可查看项目。
但是,对于像我这样的自定义对象,重写 ToString 方法可能是明智的,因为这是您将在没有任何进一步的模板定义的情况下看到的。
(附带说明,必须在控件模板中定义一个 ListView 并将其 TargetType 属性 设置为 "ListView",这有点违反直觉,但您可以将其视为也是一个要求)
我的问题的解决方案可能只是与 WPF ListViews 具体相关,但它也可能只是一般的控件模板问题。我不知道。
我有以下 3 个 属性 class,在我的代码隐藏中定义了覆盖的 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,以及在 window 的所有 3 个 class 属性的资源下定义的数据模板,以及在 class 下定义的一个 WorkListViewItem 数组=71=]网格的资源。
(DTNamey 还具有 two-way 绑定、文本框和附加的 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 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>
现在这一切都完全符合我的要求: (我缺乏 post 图片的声誉,但相信我,它确实如此!)
它显示数据数组中每个元素的 3 列和一行。 Namey 文本框的更改反映在第二列(长度)中,一切都很好。
问题:
但是,相同的 ListView 定义在放置在控件模板中时不显示任何项目。列显示得很好,但没有显示行。
Window 资源:
<!--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 控件,这与列 header 定义冲突。
我尝试在以下位置添加 ItemsPresenter:
<ListView.Items>
<ItemsPresenter/>
</ListView.Items>
我试过将 ListView 的数据上下文设置为:(完全不正确,我敢肯定)
<ListView DataContext="{Binding local:WorkListViewItem}">
我什至尝试过定义 ListView 的 ItemTemplate 属性。
我已经研究了 3 天,并决定求助于互联网。
所以我的问题是;使用控件模板时需要哪些 ListView 属性才能显示项目 collection?
感谢您的宝贵时间。
马修
2015 年 9 月 29 日更新
我发现将 ItemsPresenter 和 ContentPresenter 元素直接放在 ListView 标签下,会添加通过数据模板正确设置样式的空白项。
突破!
我发现通过将模板的 ListView 的 ItemsSource 属性 绑定到提供的 ItemsSource,所有项目都会显示,所有列都会正确填充。
<ControlTemplate TargetType="ListView" x:Key="cmonnow">
<ListView ItemsSource="{TemplateBinding ItemsSource}">
...
</ControlTemplate>
想通了
归根结底,似乎获得 ListView 控件模板以显示数据所需的唯一组件是模板 ListView 的 ItemsSource 属性。
无需手动设置 ListView 视图 属性 即可查看项目。
但是,对于像我这样的自定义对象,重写 ToString 方法可能是明智的,因为这是您将在没有任何进一步的模板定义的情况下看到的。
(附带说明,必须在控件模板中定义一个 ListView 并将其 TargetType 属性 设置为 "ListView",这有点违反直觉,但您可以将其视为也是一个要求)