简体   繁体   English

具有不同输出的WPF动态列表框

[英]WPF Dynamic Listbox with different output

At first I want to say that i searched on internet and I didn't found anything. 首先,我想说的是,我在互联网上进行搜索时没有发现任何东西。 I would like to make a dynamic song list, that when user adds a song, new object will be added with name and lenght and when he selects this song he would get a path to the selected song. 我想创建一个动态的歌曲列表,当用户添加一首歌曲时,将添加带有名称和长度的新对象,并且当他选择该歌曲时,他将获得所选歌曲的路径。 Here is code to understand better: 这是更好理解的代码:

XAML: XAML:

<Window x:Class="ListBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListBox x:Name="SongList" HorizontalAlignment="Left" Height="278" Margin="10,10,0,0" VerticalAlignment="Top" Width="248"/>
    <TextBlock HorizontalAlignment="Left" Margin="287,124,0,0" TextWrapping="Wrap" Text="Path" VerticalAlignment="Top" Width="194" Height="22"/>
    <Label Content="Song Path" HorizontalAlignment="Left" Margin="287,98,0,0" VerticalAlignment="Top" Width="194"/>
    <Button Content="Add Song" HorizontalAlignment="Left" Margin="10,293,0,0" VerticalAlignment="Top" Width="132" Click="Button_Click"/>

</Grid>

and code: 和代码:

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ListBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openfile = new OpenFileDialog();
            openfile.DefaultExt = ".mp3";
            openfile.Filter = "mp3 | *.mp3";
            Nullable<bool> result = openfile.ShowDialog();
            if (result == true)
            {
                String file = openfile.FileName;
                FileInfo fileinfo = new FileInfo(file);

                SongList.Items.Add(fileinfo.Name);
            }
        }
    }
}

so where the "Path" text box is I would like to get current selected song path. 所以我想在“路径”文本框中找到当前选定的歌曲路径。 Is it possible to make with ItemBox or I need to make array that will save all paths? 是否可以使用ItemBox进行制作,或者我需要制作将保存所有路径的数组?

at first you might want to have a look at MVVM programming. 首先,您可能需要看一下MVVM编程。 The concept is not that easy to understand, even harder to apply but once you got it you will be able to create good UI in no-time and it's especially perfect for what you are trying to do. 这个概念不是那么容易理解,甚至很难应用,但是一旦掌握了它,您将能够立即创建良好的UI,并且对于您要尝试的操作而言,它尤其完美。

Now to your problem. 现在解决您的问题。 FileInfo.Name only stores the file name not the path, so if you don't store the path separately, you won't be able to get it back from just the file name. FileInfo.Name仅存储文件名而不存储路径,因此,如果您不单独存储路径,则将无法仅从文件名取回路径。

KillaKem's solution seems pretty good, however I wouldn't recommend using the Tag property for this. KillaKem的解决方案看起来不错,但是我不建议为此使用Tag属性。 Just create a Collections::Generic::List (please, don't use arrays) class member to store the paths and then use the selectedIndexChange Event to update the PathSearchBox. 只需创建一个Collections :: Generic :: List(请不要使用数组)类成员来存储路径,然后使用selectedIndexChange事件更新PathSearchBox。

using MVVM you could just link the ListBox to a Dictionary which stores both, path and filename and just display the Filename, feel free to research MVVM a bit yourself. 使用MVVM,您可以将ListBox链接到存储路径和文件名的Dictionary,并仅显示Filename,可以随时自行研究MVVM。

Regards, Xaser 问候,Xaser

I think you should use for your songs, because you're writing a WPF application, an ObservableCollection of your song objects, in order to have a proper ListBox with your updated objects. 我想您应该为您的歌曲使用,因为您正在编写WPF应用程序,即您的歌曲对象的ObservableCollection ,以便使用更新的对象来创建适当的ListBox。

Then, you have to create a proper Song class with its own properties, like the SongName or the SongPath . 然后,您必须创建一个具有其自身属性的正确Song类,例如SongNameSongPath In this class, you will implement the INotifyPropertyChanged interface and, for each property, you will raise an appropriate OnPropertyChanged event. 在此类中,您将实现INotifyPropertyChanged接口,并且对于每个属性,您将引发一个适当的OnPropertyChanged事件。

With this implementation, once you load a song and add it to the songs list, your ListBox will show the updated collection accordingly. 使用此实现,一旦加载一首歌曲并将其添加到歌曲列表,您的ListBox将相应地显示更新后的集合。

Further info about the ObservableCollection here . 有关ObservableCollection的更多信息,请参见此处

If you want to have a look at a code sample, in this answer I written an example of developing an ObservableCollection. 如果您想看一下代码示例,请在此答案中写一个开发ObservableCollection的示例。

You could try something along the lines of this, 您可以尝试一些类似的方法,

XAML: XAML:

<Window x:Class="ListBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListBox x:Name="SongList" HorizontalAlignment="Left" Height="278" Margin="10,10,0,0" VerticalAlignment="Top" Width="248"/>
    <TextBlock HorizontalAlignment="Left" Margin="287,124,0,0" TextWrapping="Wrap" Text="Path" VerticalAlignment="Top" Width="194" Height="22"/>
    <Label Name ="pathLabel" Content="Song Path" HorizontalAlignment="Left" Margin="287,98,0,0" VerticalAlignment="Top" Width="194"/>
    <Button Content="Add Song" HorizontalAlignment="Left" Margin="10,293,0,0" VerticalAlignment="Top" Width="132" Click="Button_Click"/>

</Grid>

Back Code: 后面的代码:

namespace ListBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openfile = new OpenFileDialog();
            openfile.DefaultExt = ".mp3";
            openfile.Filter = "mp3 | *.mp3";
            Nullable<bool> result = openfile.ShowDialog();
            if (result == true)
            {
                String file = openfile.FileName;
                FileInfo fileinfo = new FileInfo(file);

                SongList.Items.Add(fileinfo.Name);

                var pathList = SongList.Tag as List<string>;
                pathList.Add(fileinfo.DirectoryName);
                SongList.Tag = pathList;
            }
        }

         private void Selection_Changed(object sender, EventArgs e)
        {
              var myListBox = sender as ListBox;
              var myPathList = myListBox.Tag as List<string>;
              var filePath = myPathList[myListBox.SelectedIndex];

              pathLabel.Content = filePath;
        }
    }
}

Haven't tested the code but it should be working or close to working. 尚未测试代码,但它应该可以工作或接近工作。

These is a SelectionChanged event in the listbox you can use. 这些是您可以使用的列表框中的SelectionChanged事件。 But i would recommend using bi 但我建议使用bi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM