C# WPF ListView ItemsSource - 设置文本和图片

C# WPF ListView ItemsSource - Setting Text & Picture

目前在我的列表视图中,我正在使用以下代码设置文本、图片和文本颜色,如下所示 - http://oi61.tinypic.com/nzggls.jpg

foreach (Mods modname in gameMods)
{
    if (Directory.Exists(Path.Combine(ArmA3PATH, "@" + modname.ModString)))
    {
        lstMods.Items.Add(new listViewItem
                (
                    modname.ModName.ToString(),
                    Path.Combine(dir, modname.ModLink),
                    new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green)
                )
            );
    }
    else
    {
        lstMods.Items.Add(new listViewItem
                (
                    modname.ModName.ToString(),
                    Path.Combine(dir, modname.ModLink),
                    new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Red)
                )
          );
    }
}

两者类如下,其中gameMods只是简单的用Mods创建的List,List

public class listViewItem
{
    public string Text { get; set; }
    public string ImagePic { get; set; }
    public System.Windows.Media.SolidColorBrush BackgroundColor { get; set; }
    public listViewItem(string text, string image, System.Windows.Media.SolidColorBrush color)
    {
        Text = text;
        ImagePic = image;
        BackgroundColor = color;
    }
}

public class Mods
{
    public string ModName { get; set; }
    public string ModVersion { get; set; }
    public string ModLink { get; set; }
    public string ModString { get; set; }
    public string ModLogo { get; set; }

    public Mods(string modName, string modVersion, string modLink, string modString, string modLogo)
    {
        this.ModName = modName;
        this.ModVersion = modVersion;
        this.ModLink = modLink;
        this.ModString = modString;
        this.ModLogo = modLogo;
    }
}

上面代码的XAML标记是

<ListView x:Name="lstMods">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <Image Source="{Binding ImagePic}" Width="80" Height="80" Stretch="Fill"/>
                <TextBlock Name="txtBlock" Text="{Binding Text}" Foreground="{Binding BackgroundColor}" VerticalAlignment="Center" TextAlignment="Center"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
        <WrapPanel Width="{Binding (FrameworkElement.ActualWidth), 
            RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
            ItemWidth="248"
            MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
            ItemHeight="{Binding (ListView.View).ItemHeight, 
            RelativeSource={RelativeSource AncestorType=ListView}}" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

现在,这很好用;但我不能像这样使用 SelectionChanged 和 SelectedItem 来获取值,那么我怎样才能在 ListView 上使用 ItemsSource 并仍然将 images/text 添加到 ListView 块?

目前,在执行 lstMods.ItemsSource = gameMods 时,ItemsSource 看起来像这样 http://oi59.tinypic.com/dwi0m.jpg

我知道那是因为没有绑定文本值,但我不太确定在何处为 Item Sourcing 添加这些值。

正如@DanielLane 提到的,在 WPF 中,我们倾向于将集合数据绑定到 UI 中的 ItemsControl。在您的情况下,您应该有一个 Items(或类似名称)属性 来保存您的 listViewItem 个实例:

<ListView x:Name="lstMods" ItemsSource="{Binding Items}">
    ...
</ListView>

然后您将代码更改为类似于以下内容:

Items.Add(new listViewItem
    (
        modname.ModName.ToString(),
        Path.Combine(dir, modname.ModLink),
        new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green)
    )
);

要使其正常工作,您需要在 class 中使用 Items 属性 实现 INotifyPropertyChanged 接口。通常,我们会添加另一个 属性 类型 listViewItem 来表示集合中的选定项目:

<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding YourSelectedItem}">
    ...
</ListView>

现在,只要在 GridView 中选择了一个新项目,就会调用 YourSelectedItem 属性 setter:

private listViewItem yourSelectedItem;
public listViewItem YourSelectedItem
{ 
    get { return yourSelectedItem; }
    set
    {
        yourSelectedItem = value;
        NotifyPropertyChanged("YourSelectedItem");
        // The selected item changed so you can do something with the new item here
     }
}

请参阅 MSDN 上的 Data Binding Overview 页面以获取更多帮助。

今天看了几分钟后,我所做的就是以下内容,这是我最初寻找的

rivate void lstMods_DblClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    var selection = lstMods.SelectedItem;
    var mod = selection as listViewItem;

    MessageBox.Show(mod.LinkUrl);
}

public class listViewItem
{
    public string Text { get; set; }
    public string ImagePic { get; set; }
    public string LinkUrl { get; set; }
    public System.Windows.Media.SolidColorBrush BackgroundColor { get; set; }
    public listViewItem(string text, string image, System.Windows.Media.SolidColorBrush color, string modlink)
    {
        Text = text;
        ImagePic = image;
        BackgroundColor = color;
        LinkUrl = modlink;
    }
}

foreach (Mods modname in gameMods)
{
    if (Directory.Exists(Path.Combine(ArmA3PATH, "@" + modname.ModString)))
    {
        lstMods.Items.Add(new listViewItem
                (
                    modname.ModName.ToString(),
                    Path.Combine(dir, modname.ModLink),
                    new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green),
                    modname.ModLink.ToString()
                )
            );
    }
    else
    {
        lstMods.Items.Add(new listViewItem
                (
                    modname.ModName.ToString(),
                    Path.Combine(dir, modname.ModLink),
                    new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Red),
                    modname.ModLink.ToString()
                )
          );
    }
}

而 XAML 是

<ListView x:Name="lstMods" MouseDoubleClick="lstMods_DblClick">

所以真的,我做的唯一改变是最初我将 SelectionChanged 称为 "Mods" class 而它应该是 listViewItem class.