ItemsSource必须要绑定到数据上
TextBlock Text={Binding} 这句话表明,Text显示Stars里面的每一条数据
在ItemsControl的Template中,加入ItemsPresenter才会显示每一个子信息的内容
一个需要注意的点:绑定的属性需要通过时间进行更新(例如需要OnPropertyChanged(nameof(xxx)))
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<ItemsControl ItemsSource="{Binding Stars}" AlternationCount="2">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<DockPanel>
<TextBlock Text="Header"
FontSize="18"
DockPanel.Dock="Top"/>
<ItemsPresenter/>
</DockPanel>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border x:Name="border" Padding="10">
<TextBlock Text="{Binding}"/>
</Border>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter TargetName="border" Property="Background" Value="LightGray"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
public class ViewModel
{
public ObservableCollection<string> Stars { get; } = new ObservableCollection<string>() { "Mercucy", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune" };
}
---------这是分割线-----------
不同的属性 更改成不同的属性
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
// 绑定对应数据源
<ItemsControl ItemsSource="{Binding Shapes}">
// 指定整体的容器控件是什么
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
// 给每一个item里的数据添加Style
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Pos.X}"/>
<Setter Property="Canvas.Top" Value="{Binding Pos.Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
// 给每一个item添加一个Template
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle x:Name="rect"
Width="40"
Height="40"
Fill="{Binding Color}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="1">
<Setter TargetName="rect" Property="RadiusX" Value="20"/>
<Setter TargetName="rect" Property="RadiusY" Value="20"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这个是后台属性代码
public class ViewModel
{
public ObservableCollection<Shape> Shapes { get; } = new ObservableCollection<Shape> {
new Shape(){Type = 0,Pos = new Point(50,50),Color = Brushes.Red},
new Shape(){Type = 1,Pos = new Point(150,70),Color = Brushes.Green},
new Shape(){Type = 1,Pos = new Point(300,160),Color = Brushes.Blue},
new Shape(){Type = 0,Pos = new Point(240,260),Color = Brushes.Yellow},
};
}
public class Shape:INotifyPropertyChanged
{
private int _type;
public int Type
{
get { return _type; }
set
{
if (_type != value)
{
_type = value;
OnPropertyChanged(nameof(Pos));
}
}
}
private Point _pos;
public Point Pos
{
get { return _pos; }
set
{
if (_pos != value)
{
_pos = value;
OnPropertyChanged(nameof(Pos));
}
}
}
private Brush _color;
public Brush Color
{
get { return _color; }
set
{
if(_color != value)
{
_color = value;
OnPropertyChanged(nameof(Color));
}
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
---------分割线---------------
不同的类显示不同的控件
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<ItemsControl Padding="5" VerticalAlignment="Top" ItemsSource="{Binding Fruits}">
// 标注item的容器控件是什么
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
// 原本是ItemsControl.ItemTemplate,后改为ItemsControl.Resources,这样就可以在里面放多个不同的控件
// 这里的特点是DataType="{x:Type local:Apple},这里可以指定不同的类型,但如果属性都一致的话就不行了
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:Apple}">
<Border Height="{Binding RelativeSource={RelativeSource Self},Path=ActualWidth}"
Margin="5"
BorderThickness="1"
Background="LightCoral"
BorderBrush="Gray">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Amount,StringFormat=Amount:{0}}"/>
</Border>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Banana}">
<Button Height="{Binding RelativeSource={RelativeSource Self},Path=ActualWidth}"
Margin="5"
BorderThickness="1"
Background="LightYellow"
BorderBrush="Gray">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Amount,StringFormat=Amount:{0}}"/>
</Button>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
public class ViewModel
{
public ObservableCollection<Fruit> Fruits { get; } =
new ObservableCollection<Fruit>
{
new Apple{Amount = 3},
new Apple{Amount = 2},
new Banana{Amount = 6},
new Apple{Amount = 4},
new Banana{Amount = 1},
new Banana{Amount = 5}
};
}
public abstract class Fruit
{
public int Amount { get; set; }
}
public class Apple : Fruit { }
public class Banana : Fruit { }
-----------分割线-----------
不同的属性,显示不同的控件
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Window.Resources>
// 将这个方法引用进资源里面
<local:EmployeeTemplateSelector x:Key="EmployeeTemplateSelector"/>
</Window.Resources>
<ItemsControl Padding="5" VerticalAlignment="Top" ItemsSource="{Binding Employees}" ItemTemplateSelector="{StaticResource EmployeeTemplateSelector}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
// 选择哪种DataTemplate
<DataTemplate x:Key="male">
<Border Height="200" Background="LightCyan">
<TextBlock Text="{Binding Name}"/>
</Border>
</DataTemplate>
<DataTemplate x:Key="female">
<Border Height="200" Background="LightCyan">
<TextBlock Text="{Binding Name}"/>
</Border>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
public class ViewModel
{
public ObservableCollection<Employee> Employees { get; } = new ObservableCollection<Employee>
{
new Employee(){Name="John",Gender = Gender.Male},
new Employee(){Name="Anna",Gender = Gender.Female},
new Employee(){Name="Joyce",Gender = Gender.Female},
new Employee(){Name="Tony",Gender = Gender.Male},
new Employee(){Name="Brian",Gender = Gender.Male},
};
}
public class Employee: INotifyPropertyChanged
{
private string name;
public string Name
{
get { return name; }
set {
if (name != value)
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
}
private Gender gender;
public Gender Gender
{
get { return gender; }
set
{
if (gender != value)
{
gender = value;
OnPropertyChanged(nameof(Gender));
}
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public enum Gender
{
Male,
Female
}
public class EmployeeTemplateSelector:DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
// 拿到对应的Resource
var element = container as FrameworkElement;
var employee = item as Employee;
return employee.Gender switch
{
Gender.Male => element.FindResource("male") as DataTemplate,
Gender.Female => element.FindResource("female") as DataTemplate,
_ => throw new ArgumentException()
};
}
}