[英]How do I add, save and load items to a listview in WPF
About two weeks ago I started to develop in WPF and, since I only developed in WinForms, I ran into common problems but managed to find the solution for them. 大约两周前,我开始在WPF中开发,因为我只是在WinForms中开发,所以我遇到了常见的问题,但设法找到了解决方案。 However, currently I'm stuck at something: adding items with multiple columns (via visual basic code, not xaml) into a listview. 但是,目前我已经陷入困境:将具有多个列的项目(通过可视化基本代码,而不是xaml)添加到列表视图中。
I'm not sure if it's best to use a Listview or a DataGrid control for this but basically I want the user to be able to add favourite songs to a list, save them to a file and load the file whenever the app is opened. 我不确定是否最好使用Listview或DataGrid控件,但基本上我希望用户能够将喜欢的歌曲添加到列表中,将它们保存到文件并在应用程序打开时加载文件。 The listview currently has three columns: Artist, Song and Status. 列表视图目前有三列:艺术家,歌曲和状态。
When I was programming in WinForms, I used to do this: 当我在WinForms中编程时,我曾经这样做过:
Dim Song As New ListViewItem
Form1.ListView1.Items.Add(Song)
Song.Text = TextBox1.Text
Song.SubItems.Add(TextBox2.Text)
Song.SubItems.Add(TextBox3.Text)
Then, to save: 然后,保存:
Dim Song As New ListViewItem
Form1.ListView1.Items.Add(Song)
Song.Text = TextBox1.Text
Song.SubItems.Add(TextBox2.Text)
Song.SubItems.Add(TextBox3.Text)
Try
Dim myWriter As New IO.StreamWriter(PATH_DATABASE)
For Each myItem As ListViewItem In Form1.ListView1.Items
myWriter.WriteLine(myItem.Text & "|" & myItem.SubItems(1).Text & "|" & myItem.SubItems(2).Text & "|" & myItem.SubItems(3).Text
Next
myWriter.Close()
Catch ex As Exception
MsgBox("Error: " & ex.Message, vbCritical, "Error")
End Try
I've been searching and I've found that I need to use binding so I've tried this: 我一直在寻找,我发现我需要使用绑定,所以我试过这个:
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Windows
Public Structure Song
Public _artist As String
Public _title As String
Public _status As String
Property Artist() As String
Get
Return _artist
End Get
Set(ByVal Value As String)
_artist = Value
End Set
End Property
Property Title() As String
Get
Return _title
End Get
Set(ByVal Value As String)
_title = Value
End Set
End Property
Property Status() As String
Get
Return _status
End Get
Set(ByVal Value As String)
_status = Value
End Set
End Property
End Structure
Public Class WINDOW_AddSong
Dim songs As New ObservableCollection(Of Song)
Private Sub Button1_Click(sender As Object, e As RoutedEventArgs) Handles Button1.Click
Dim Song As New ListViewItem
For Each wnd As Window In Application.Current.Windows
If wnd.GetType Is GetType(MainWindow) Then
DirectCast(wnd, MainWindow).Listview1.Items.Add(Alimento)
Alimento.Content = New Song() With {._artist = "Lol", ._title = "Lol2", ._status = "Lol3"}
End If
Next
End Sub
End Class
And in the XAML listview: 在XAML列表视图中:
<GridViewColumn Header="Artist" DisplayMemberBinding="{Binding Artist}"/>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}"/>
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding Status}"/>
This works however I'm not sure if this is the WPF-way of doing things. 这可行,但我不确定这是否是WPF的做事方式。
However, I'm stuck at the saving process: 但是,我陷入了保存过程:
Try
Dim myWriter As New IO.StreamWriter(PATH_DATABASE)
For Each wnd As Window In Application.Current.Windows
If wnd.GetType Is GetType(MainWindow) Then
For Each myItem As ListViewItem In DirectCast(wnd, MainWindow).Listview1.Items
myWriter.WriteLine(Song, Artist, Status)
Next
End If
Next
myWriter.Close()
Catch ex As Exception
MsgBox("Error: " & ex.Message, vbCritical, "Error")
End Try
This doesn't work. 这不起作用。 Also, PATH_DATABASE is just a directory. 此外,PATH_DATABASE只是一个目录。
To summarise, could an expert review my code and check if I'm doing things "right" and, if possible, could you help me with the saving and loading process? 总而言之,专家是否可以检查我的代码并检查我是否做得“正确”,如果可能的话,您可以帮我保存和加载过程吗?
Thanks. 谢谢。
I just updated your structure (I used a class, just force of habit) to use automatic property values which are available in recent versions of VS. 我刚刚更新了你的结构(我使用了一个类,只是习惯的力量)来使用最新版本的VS中提供的自动属性值。 The default implementation of properties is built in along with the backer fields. 默认的属性实现与backer字段一起构建。 It is used just as before. 它像以前一样使用。
You are on the right track with ObservableCollection but you you need to implement INotifyPropertyChanged by adding the Event PropertyChanged and providing the Sub OnPropertyChanged to raise the event. 您使用ObservableCollection在正确的轨道上,但是您需要通过添加Event PropertyChanged并提供Sub OnPropertyChanged来引发事件来实现INotifyPropertyChanged。
Set up the bindings on the controls and set the ItemsSource ot the ListView to your ObservableList. 在控件上设置绑定,并将ListS的ItemsSource设置为ObservableList。
To save Import System.Text so you can use a StringBuilder. 要保存Import System.Text,以便可以使用StringBuilder。 The loop through the list to build the string to save to a text file. 循环遍历列表以构建保存到文本文件的字符串。
I didn't spend any time trying to make the XAML Windows look nice. 我没有花时间试图让XAML Windows看起来不错。 Pardon the ugliness. 请原谅丑陋。
Class MainWindow
Public Songs As New ObservableCollection(Of Song)
Protected Sub OnLoad(sender As Object, e As RoutedEventArgs)
Songs.Add(New Song("Nirvana", "Smells Like Teen Spirit", "Open"))
Songs.Add(New Song("John Lennon", "Imagine", "In Stock"))
Songs.Add(New Song("U2", "One", "Unknown"))
Songs.Add(New Song("Michael Jackson", "Billie Jean", "Open"))
lvSongs.ItemsSource = Songs
End Sub
Private Sub BtnAdd_Click(sender As Object, e As RoutedEventArgs)
Dim frm As New frmAdd
frm.mainForm = Me 'send the instance of the current form to the new form
frm.ShowDialog()
End Sub
Private Sub SaveList()
Dim sb As New StringBuilder
For Each item As Song In Songs
sb.AppendLine($"{item.Artist}|{item.Title}|{item.Status}")
Next
'call sb.ToString and write it to a .txt file
End Sub
End Class
MainWindow XAML MainWindow XAML
<Window x:Class="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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_BindComboBox"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Loaded="OnLoad"
Name="root">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView Margin="10" Name="lvSongs" Grid.Row="0">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="Name: " />
<TextBox x:Name="txtArtist"
Text="{Binding Artist, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
FontWeight="Bold"/>
<TextBlock Text=", " />
<TextBlock Text="Age: " />
<TextBox Text="{Binding Title}"
FontWeight="Bold" />
<TextBlock Text=" (" />
<TextBox Text="{Binding Status}" />
<TextBlock Text=")" />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button x:Name="btnAdd" Grid.Row="1" Height="25" Width="100" Content="Add a Song" Click="BtnAdd_Click"/>
</Grid>
</Window>
The Song class 宋班
Public Class Song
Implements INotifyPropertyChanged
Public Property Artist() As String
Public Property Title() As String
Public Property Status() As String
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(ByVal name As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub
Public Sub New(art As String, Ttl As String, Stat As String)
Artist = art
Title = Ttl
Status = Stat
End Sub
End Class
The Add Window 添加窗口
Public Class frmAdd
Public mainForm As MainWindow
Private Sub BtnAdd_Click(sender As Object, e As RoutedEventArgs)
mainForm.Songs.Add(New Song(txtArtist.Text, txtTitle.Text, txtStatus.Text))
ClearForm()
End Sub
Private Sub ClearForm()
txtArtist.Clear()
txtTitle.Clear()
txtStatus.Clear()
End Sub
End Class
Add Window XAML 添加窗口XAML
<Window x:Class="frmAdd"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_BindComboBox"
mc:Ignorable="d"
Title="frmAdd" Height="172.641" Width="307.547">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Artist" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="txtArtist" Grid.Column="1" Grid.Row="0" FontSize="16" Width="150" />
<TextBlock Grid.Column="0" Grid.Row="1" Text="Title" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="txtTitle" Grid.Column="1" Grid.Row="1" FontSize="16" Width="150"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Status" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="txtStatus" Grid.Column="1" Grid.Row="2" FontSize="16" Width="150"/>
<Button x:Name="btnAdd" Grid.Column="1" Grid.Row="4" Content="Add Song" Click="BtnAdd_Click"/>
</Grid>
</Window>
EDIT Required Imports 编辑所需的进口
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.Text
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.