Лучший способ сделать это - использовать UniformGrid
в качестве ItemsPanel
ListView
.
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
...
</ListView>
Вот пример того, как сделать это с ListBox
вместо ListView
, как обсуждалось в комментариях.Я бы рекомендовал этот способ, если вам не нужны некоторые специальные функции ListView
, так как он будет более производительным.
При этом используется AgentOctal.WpfLib пакет NuGet (Я являюсь автором этого пакета) для базового класса ViewModel
для предоставления уведомлений об изменениях свойств и поддержки команд.Вы должны иметь возможность заменить любой рабочий метод, который правильно реализует INotifyPropertyChanged
.
XAML:
<Window
x:Class="ColumnsTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ListViewColumns"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.DataContext>
<local:MainWindowVm />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox
Grid.Row="0"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
ItemsSource="{Binding Path=People}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border
Height="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth}"
Margin="4"
BorderBrush="Black"
BorderThickness="1">
<TextBlock Text="{Binding Path=Name}" />
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button
Grid.Row="1"
Command="{Binding Path=AddPersonCommand}"
Content="Add Person" />
</Grid>
</Window>
Просмотр моделей:
namespace ColumnsTest
{
using System.Windows.Input;
using AgentOctal.WpfLib;
using AgentOctal.WpfLib.Commands;
class MainWindowVm : ViewModel
{
public MainWindowVm()
{
People = new ObservableCollection<PersonVm>();
}
public ObservableCollection<PersonVm> People { get; }
private ICommand _addPersonCommand;
public ICommand AddPersonCommand
{
get
{
return _addPersonCommand ?? (_addPersonCommand = new SimpleCommand((obj) =>
{
People.Add(new PersonVm() { Name = Guid.NewGuid().ToString() });
}));
}
}
class PersonVm : ViewModel
{
private string _name;
public string Name
{
get { return _name; }
set { SetValue(ref _name, value); }
}
}
}
Он производит следующиерезультат: ![enter image description here](https://i.stack.imgur.com/l4cCa.png)