我想在ListView
中显示不同行(不同风格和不同内容)的数据。但是一旦我尝试应用一种风格(假设什么都不改变),选择就会停止工作,而且它不再是Vista style。
我做错了什么?也许是错误的做法?
<ListView ItemsSource="{Binding A}">
<ListView.View>
<GridView>
<GridViewColumn Header="B" DisplayMemberBinding="{Binding B}"/>
...
</GridView>
</ListView.View>
<!-- commenting below block will return Vista style back -->
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<GridViewRowPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
答案 0 :(得分:2)
如果您希望在ControlTemplate
中显示不同行(不同风格和不同内容)的数据,则不应更改ListViewItem
的{{1}}。
请改用ListView
。您可以根据绑定的数据类型设置行的样式。
假设你有一个这样的视图模型:
DataTemplate
然后,只需为要在列表视图中显示的项目定义public class ViewModel : INotifyPropertyChanged
{
public List<object> A { get; private set; }
public ViewModel()
{
this.A = new List<object> { Brushes.BlueViolet, 42, false };
}
}
:
DataTemplate
使用这种方法,您将获得代表您的数据的列表视图行,保留核心<ListView ItemsSource="{Binding A}">
<ListView.View>
<GridView>
<GridViewColumn Header="B"/>
</GridView>
</ListView.View>
<ListView.Resources>
<DataTemplate DataType="{x:Type media:Brush}">
<Rectangle Width="25" Height="25" Fill="{Binding Mode=OneWay}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type sys:Boolean}">
<CheckBox IsChecked="{Binding Mode=OneWay}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type sys:Int32}">
<TextBlock Text="{Binding Mode=OneWay}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ListView.Resources>
</ListView>
功能和“Vista样式”。
答案 1 :(得分:1)
我尽量保持它尽可能通用,所以我为每行可以采用的不同类型定义一个简单的枚举:
public enum RowType { Bool, Int32 }
现在我在行的视图模型中使用它:
public class Row: DependencyObject
{
//create a new row with the given value
//automatically set Value, Info and RowType based on the param
public Row(object val)
{
Value = val;
if (val.GetType() == typeof(bool)) RowType = WpfApplication3.RowType.Bool;
else RowType = WpfApplication3.RowType.Int32;
Info = val.ToString() + " of type " +val.GetType().ToString();
}
public RowType RowType { get; set; }
/// <summary>
/// Gets or sets a bindable value that indicates Value
/// </summary>
public object Value
{
get { return (object)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(object), typeof(Row), new PropertyMetadata(0));
/// <summary>
/// Gets or sets a bindable value that indicates Info
/// </summary>
public string Info
{
get { return (string)GetValue(InfoProperty); }
set { SetValue(InfoProperty, value); }
}
public static readonly DependencyProperty InfoProperty =
DependencyProperty.Register("Info", typeof(string), typeof(Row), new PropertyMetadata(""));
}
现在视图模型已准备就绪,我创建了一个简单的TemplateSelector,它响应给定行的RowType:
public class Selector : DataTemplateSelector
{
//Template for RowType==Bool
public DataTemplate Template1 { get; set; }
//Template for RowType==Int32
public DataTemplate Template2 { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var row = item as Row;
if (row == null) return null;
switch (row.RowType)
{
case RowType.Bool:
return Template1;
case RowType.Int32:
return Template2;
default:
return null;
}
}
}
我在Xaml中使用它像这样:
<Window.Resources>
<!-- selects CellTemplate for column1 (Value) based on RowType -->
<local:Selector x:Key="valueSelector">
<local:Selector.Template1>
<DataTemplate>
<CheckBox IsChecked="{Binding Value, Mode=OneWay}"/>
</DataTemplate>
</local:Selector.Template1>
<local:Selector.Template2>
<DataTemplate>
<TextBlock Text="{Binding Value, Mode=OneWay}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</local:Selector.Template2>
</local:Selector>
<!-- selects CellTemplate for column2 (Info) based on RowType -->
<local:Selector x:Key="infoSelector">
<local:Selector.Template1>
<DataTemplate>
<Canvas Height="16">
<TextBlock Text="{Binding Info, Mode=OneWay}"
Foreground="Blue" VerticalAlignment="Top"/>
</Canvas>
</DataTemplate>
</local:Selector.Template1>
<local:Selector.Template2>
<DataTemplate>
<Canvas Height="16">
<TextBlock Text="{Binding Info, Mode=OneWay}"
VerticalAlignment="Top"/>
</Canvas>
</DataTemplate>
</local:Selector.Template2>
</local:Selector>
</Window.Resources>
<ListView ItemsSource="{Binding A}">
<ListView.View>
<GridView>
<GridViewColumn Header="Value"
CellTemplateSelector="{StaticResource valueSelector}"/>
<GridViewColumn Header="Info" Width="0"
CellTemplateSelector="{StaticResource infoSelector}"/>
</GridView>
</ListView.View>
</ListView>
结果如下:
并非我根据dymanoid的答案写了这个答案,答案是基于给定的信息准确的。