如何以编程方式将多个字符串添加到多列 ListView 中的一行
How to programmatically add multiple strings to one line in a multiple column ListView
所以我是WPF的新手,对WinForms比较熟悉,但是为了绘图性能和好看UI我转用WPF,我没有经验XAML 但我正在解决我的问题。
我有一个 ListView
作为我的媒体播放器应用程序的播放列表。在一行多列中添加多个数据在 WinForms 中不是问题,我只需要添加一个 ListViewItem
并填充它 SubItems
,但在 WPF 中这是一个问题, ListViewItem
没有 SubItems
属性 也没有 ListView
,我尝试了 Stack Overflow 和其他网站的多个问题,但对我没有帮助,都是关于 DisplayMemberBinding
但是我仍然不能/不知道如何在我的代码中引用它。
XAML 对于 ListView
:
<ListView x:Name="Playlist_Main" Margin="0" ItemsSource="{Binding SourceCollection}">
<ListView.View>
<GridView>
<GridViewColumn Header="#" DisplayMemberBinding="{Binding Num}"/>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}"/>
<GridViewColumn Header="Artist" DisplayMemberBinding="{Binding Artist}"/>
<GridViewColumn Header="Album" DisplayMemberBinding="{Binding Album}"/>
<GridViewColumn Header="Year" DisplayMemberBinding="{Binding Year}"/>
<GridViewColumn Header="Track Num" DisplayMemberBinding="{Binding Track}"/>
</GridView>
</ListView.View>
</ListView>
主要代码
Playlist_Main.Items.Add(New ListViewItem({Playlist_Main.Items.Count + 1, Info(0), Info(1), Info(2), Info(3), Info(4)}))
您的 ListView
/ GridView
中的绑定需要一个公开 Num
、Title
等属性的项目类型。您必须公开该项目类型的集合并将其分配或绑定到 ItemsSource
属性.
为播放列表中的项目创建模型。如果 属性 值更改,以下示例将实现 INotifyPropertyChanged
interface that enables bindings to update through the PropertyChanged
事件。如果您的属性是只读的或者您不需要在运行时更新值,则不必实现它。
public class PlaylistItem : INotifyPropertyChanged
{
private int _num;
private string _title;
private string _artist;
private string _album;
private int _year;
private int _track;
public PlaylistItem(int num, string title, string artist, string album, int year, int track)
{
Num = num;
Title = title;
Artist = artist;
Album = album;
Year = year;
Track = track;
}
public int Num
{
get => _num;
set
{
if (_num == value)
return;
_num = value;
OnPropertyChanged();
}
}
public string Title
{
get => _title;
set
{
if (_title == value)
return;
_title = value;
OnPropertyChanged();
}
}
public string Artist
{
get => _artist;
set
{
if (_artist == value)
return;
_artist = value;
OnPropertyChanged();
}
}
public string Album
{
get => _album;
set
{
if (_album == value)
return;
_album = value;
OnPropertyChanged();
}
}
public int Year
{
get => _year;
set
{
if (_year == value)
return;
_year = value;
OnPropertyChanged();
}
}
public int Track
{
get => _track;
set
{
if (_track == value)
return;
_track = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
在代码隐藏方法中,您可以创建 PlaylistItem
的集合。使用 ObservableCollection<T>
that implements the INotifyCollectionChanged
interface, if you want to reflect changes to the collection in the user interface, e.g. adding or removing items. The ObservableCollection<T>
does that automatically through the CollectionChanged
事件。如果您的列表在运行时未被修改,您可以使用任何其他集合。
var playlistItems = new ObservableCollection<PlaylistItem>();
playlistItems.Add(new PlaylistItem(1, "Enter Sandman", "Metallica", "Metallica", 1991, 1));
// ...add other playlist items.
您可以将此集合直接分配给 ListView
,例如在构造函数中。
public MainWindow()
{
var playlistItems = // ...create the items collection or load them from somewhere.
Playlist_Main.ItemsSource = playlistItems;
}
另一种方法是在代码隐藏中创建 public 属性。我假设它是 MainWindow
.
public partial class MainWindow
{
public MainWindow()
{
PlaylistItems = // ...create the items collection or load them from somewhere.
}
public ObservableCollection<PlaylistItem> PlaylistItems { get; }
}
您将在 XAML 中使用 RelativeSource
绑定到 window.
中绑定此集合
<ListView ItemsSource="{Binding Tracks, RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}">
如您所见,方法有很多种,甚至更多。在我看来,最好的方法是使用 MVVM 模式。为此,您将为包含集合的主要 window 创建一个视图模型。
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
PlaylistItems = // ...create the items collection or load them from somewhere.
}
public ObservableCollection<PlaylistItem> PlaylistItems { get; }
// ...other properties and methods.
}
接下来,您可以将此视图模型的实例设置为 window 的 DataContext
。
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
然后你可以像这样绑定到集合。数据上下文 (MainViewModel
) 自动继承。
<ListView ItemsSource="{Binding PlaylistItems}">
此模式可帮助您将用户界面与数据和业务逻辑分开。如您所见,没有从视图模型到视图的引用,只有公开可以绑定的数据的属性。
更多学习资源:
所以我是WPF的新手,对WinForms比较熟悉,但是为了绘图性能和好看UI我转用WPF,我没有经验XAML 但我正在解决我的问题。
我有一个 ListView
作为我的媒体播放器应用程序的播放列表。在一行多列中添加多个数据在 WinForms 中不是问题,我只需要添加一个 ListViewItem
并填充它 SubItems
,但在 WPF 中这是一个问题, ListViewItem
没有 SubItems
属性 也没有 ListView
,我尝试了 Stack Overflow 和其他网站的多个问题,但对我没有帮助,都是关于 DisplayMemberBinding
但是我仍然不能/不知道如何在我的代码中引用它。
XAML 对于 ListView
:
<ListView x:Name="Playlist_Main" Margin="0" ItemsSource="{Binding SourceCollection}">
<ListView.View>
<GridView>
<GridViewColumn Header="#" DisplayMemberBinding="{Binding Num}"/>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}"/>
<GridViewColumn Header="Artist" DisplayMemberBinding="{Binding Artist}"/>
<GridViewColumn Header="Album" DisplayMemberBinding="{Binding Album}"/>
<GridViewColumn Header="Year" DisplayMemberBinding="{Binding Year}"/>
<GridViewColumn Header="Track Num" DisplayMemberBinding="{Binding Track}"/>
</GridView>
</ListView.View>
</ListView>
主要代码
Playlist_Main.Items.Add(New ListViewItem({Playlist_Main.Items.Count + 1, Info(0), Info(1), Info(2), Info(3), Info(4)}))
您的 ListView
/ GridView
中的绑定需要一个公开 Num
、Title
等属性的项目类型。您必须公开该项目类型的集合并将其分配或绑定到 ItemsSource
属性.
为播放列表中的项目创建模型。如果 属性 值更改,以下示例将实现 INotifyPropertyChanged
interface that enables bindings to update through the PropertyChanged
事件。如果您的属性是只读的或者您不需要在运行时更新值,则不必实现它。
public class PlaylistItem : INotifyPropertyChanged
{
private int _num;
private string _title;
private string _artist;
private string _album;
private int _year;
private int _track;
public PlaylistItem(int num, string title, string artist, string album, int year, int track)
{
Num = num;
Title = title;
Artist = artist;
Album = album;
Year = year;
Track = track;
}
public int Num
{
get => _num;
set
{
if (_num == value)
return;
_num = value;
OnPropertyChanged();
}
}
public string Title
{
get => _title;
set
{
if (_title == value)
return;
_title = value;
OnPropertyChanged();
}
}
public string Artist
{
get => _artist;
set
{
if (_artist == value)
return;
_artist = value;
OnPropertyChanged();
}
}
public string Album
{
get => _album;
set
{
if (_album == value)
return;
_album = value;
OnPropertyChanged();
}
}
public int Year
{
get => _year;
set
{
if (_year == value)
return;
_year = value;
OnPropertyChanged();
}
}
public int Track
{
get => _track;
set
{
if (_track == value)
return;
_track = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
在代码隐藏方法中,您可以创建 PlaylistItem
的集合。使用 ObservableCollection<T>
that implements the INotifyCollectionChanged
interface, if you want to reflect changes to the collection in the user interface, e.g. adding or removing items. The ObservableCollection<T>
does that automatically through the CollectionChanged
事件。如果您的列表在运行时未被修改,您可以使用任何其他集合。
var playlistItems = new ObservableCollection<PlaylistItem>();
playlistItems.Add(new PlaylistItem(1, "Enter Sandman", "Metallica", "Metallica", 1991, 1));
// ...add other playlist items.
您可以将此集合直接分配给 ListView
,例如在构造函数中。
public MainWindow()
{
var playlistItems = // ...create the items collection or load them from somewhere.
Playlist_Main.ItemsSource = playlistItems;
}
另一种方法是在代码隐藏中创建 public 属性。我假设它是 MainWindow
.
public partial class MainWindow
{
public MainWindow()
{
PlaylistItems = // ...create the items collection or load them from somewhere.
}
public ObservableCollection<PlaylistItem> PlaylistItems { get; }
}
您将在 XAML 中使用 RelativeSource
绑定到 window.
<ListView ItemsSource="{Binding Tracks, RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}">
如您所见,方法有很多种,甚至更多。在我看来,最好的方法是使用 MVVM 模式。为此,您将为包含集合的主要 window 创建一个视图模型。
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
PlaylistItems = // ...create the items collection or load them from somewhere.
}
public ObservableCollection<PlaylistItem> PlaylistItems { get; }
// ...other properties and methods.
}
接下来,您可以将此视图模型的实例设置为 window 的 DataContext
。
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
然后你可以像这样绑定到集合。数据上下文 (MainViewModel
) 自动继承。
<ListView ItemsSource="{Binding PlaylistItems}">
此模式可帮助您将用户界面与数据和业务逻辑分开。如您所见,没有从视图模型到视图的引用,只有公开可以绑定的数据的属性。
更多学习资源: