如何使用数据绑定在WPF ListBox中显示单个项目名称?

时间:2016-06-09 22:34:04

标签: c# wpf mvvm data-binding listbox

在我的WPF应用程序中,我的主屏幕中有一个ListBox。我试图使用MVVM模式,因此我有一个与View关联的ViewModel。当我启动应用程序时,我的ViewModel被启动,并且它读入了我放在目录中的一堆DLL。每个DLL包含一个"策略" class,所以当我读取DLL时,我检索这些Strategy类对象并将它们放在一个列表中(实际上是一个ObservableCollection),它是我的ViewModel的成员。我使用这个名为DllList的成员列表来填充ListBox。

我的ViewModel如下所示(为清晰起见,删除了不必要的位):

if ($merk === Volvo)

然后在我的主视图中,我按如下方式绑定它。

if ($merk === 'Volvo')

当我这样做并运行应用程序时,我的列表框如下所示。

enter image description here

问题是当我尝试在Strategy对象中显示属性时。我的Strategy类包含另一个名为StratInfo的类,它又包含一个字符串属性StrategyName。我的要求是将此字符串值显示为列表框项值而不是您在上面看到的内容。

所以我在我的视图中执行以下操作:

public class ViewModelPDMain : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName) {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public ViewModelPDMain() {
        dllList = new ObservableCollection<Strategy>();
        selectedStrategy = new Strategy();
    }

    private ObservableCollection<Strategy> dllList = null;
    private Strategy selectedStrategy = null;
    public ObservableCollection<Strategy> DllList
    {
        get { return dllList; }
        set {
            dllList = value;
            RaisePropertyChanged("DllList");
        }
    }

    public Strategy SelectedStrategy
    {
        get { return selectedStrategy; }
        set {
            selectedStrategy = value;
            RaisePropertyChanged("SelectedStrategy");
        }
    }
}

当我这样做时,我希望列表框项包含一个标签,并显示我的StrategyName值。但是,我得到一个包含25个项目的列表框(我有25个DLL),但所有25个项目都是空的。

有趣的是,我尝试将SelectedStrategy.StratInfo.StrategyName绑定到文本框Text属性,并且它有效。也就是说,当我单击任何空的列表框项时,它会在文本框中显示StrategyName。请参考下图。您可以看到列表框包含项目,但不显示内容值。此外,在右侧,策略名称文本框是一个文本框,我绑定了SelectedStrategy.StratInfo.StrategyName,它在项目选择事件上显示正确的值。

enter image description here

我在一个更简单的项目中完成了同样的事情,它运行得很好。我无法弄清楚我在这里做错了什么。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您在数据模板中的绑定不正确。数据模板中的数据上下文是DllList中的一个类型为Strategy的项。所以你的标签应该是这样的:

<Label Name="lblFirstName"
       Content="{Binding StratInfo.StrategyName, Mode=OneWay}"
       Grid.Column="0"/>