将列表框绑定到 ObservableCollection

Posted

技术标签:

【中文标题】将列表框绑定到 ObservableCollection【英文标题】:Binding a Listbox to a ObservableCollection 【发布时间】:2018-08-13 16:40:53 【问题描述】:

所以我正在尝试绑定以下 ViewModel:

public class ViewModel : INotifyPropertyChanged

    private ObservableCollection<ListBoxItem> _PlacesOrCities;
    public ObservableCollection<ListBoxItem> PlacesOrCities
    
        get  return _PlacesOrCities; 
        set  _PlacesOrCities = value; RaisePropertyChanged("PlacesOrCities"); 
    

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    

    public ViewModel()
    
        _PlacesOrCities = new ObservableCollection<ListBoxItem>();
    

到以下xaml:

<ListBox Name="lbPlacesCity" ItemsSource="Binding Path=(gms:MainWindow.ViewModel).PlacesOrCities, UpdateSourceTrigger=PropertyChanged">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="models:ListBoxItem">
            <TextBlock Style="StaticResource  MaterialDesignBody2TextBlock" Text="Binding Name" Visibility="Binding Visibility" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

在代码隐藏中:

public ViewModel ViewModel  get; set; 

public MainWindow()

    InitializeComponent();
    ViewModel = new ViewModel();
    DataContext = ViewModel;

在触发按钮单击事件时,我尝试使用内存列表设置可观察集合的值:

private void StateProvince_SelectionChanged(object sender, SelectionChangedEventArgs e)

    _CurrentSelectionPlaces = Canada.Provinces
        .FirstOrDefault(x => x.Abbreviation == _SelectedStateProvince_ShortName)
        .Place.OrderBy(x => x.Name).ToList();
    foreach (var currentSelectionPlace in _CurrentSelectionPlaces)
    
        ViewModel.PlacesOrCities.Add(currentSelectionPlace);
        

但似乎没有任何项目被添加到集合中。我是不是绑定错了?

我尝试了很多解决方案,但似乎都没有改变结果 - 列表中的任何项目都没有正确加载到集合中。

编辑: 可能值得注意的是,ViewModel 中看到的 ListBoxItem 是自定义模型:

public class ListBoxItem

    [J("Name")] public string Name  get; set; 
    [J("PostalCodes")] public string[] PostalCodes  get; set; 
    public Visibility Visibility  get; set;  = Visibility.Visible;

【问题讨论】:

在运行应用程序时,您应该会在Output 窗口中看到绑定错误。尝试从那里找出问题所在 输出中没有产生错误 【参考方案1】:

您应该尝试适应 MVVM 模式,因此列表的填充应该发生在视图模型级别,而不是在视图背后的代码中。

您提到您使用点击事件,而不是这样做,尝试将按钮的命令属性绑定到视图模型中的命令,请参阅此链接,其中包含几种类型的命令以及如何使用它们的说明: https://msdn.microsoft.com/en-us/magazine/dn237302.aspx

另一方面,如果您已经在窗口构造函数中设置了数据上下文,则要绑定 ListBox 项目源,您只需要绑定的属性名称“PlacesOrCities”:

<ListBox Name="lbPlacesCity" ItemsSource="Binding Path=PlacesOrCities, UpdateSourceTrigger=PropertyChanged">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="models:ListBoxItem">
            <TextBlock Style="StaticResource  MaterialDesignBody2TextBlock" Text="Binding Name" Visibility="Binding Visibility" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

也建议尝试在没有任何模板的情况下加载列表中的项目,您可以使用 ListBox DisplayMemberPath 属性来显示名称,一旦您能够加载项目,应用样式。

同样在你使用 ObservableCollection 的方式上,你实际上需要替换整个集合而不是添加到触发 RaisePropertyChanged,而是尝试一个普通的属性。

public ObservableCollection<ListBoxItem> PlacesOrCities get;set; = new ObservableCollection<ListBoxItem>();

修改集合会更新 UI,因此无论何时使用 Add 或 Clear,UI 都应该知道。

希望对你有帮助。

【讨论】:

以上是关于将列表框绑定到 ObservableCollection的主要内容,如果未能解决你的问题,请参考以下文章

如何将列表绑定到组合框?

QML - 无法将组合框模型绑定到变体列表项

将 ObservableCollection 绑定到 WPF 列表框

将代码数据绑定到 XAML 透视列表框

如何将 DataGrid 中的文本框绑定到 Wpf 中的列表?

我们如何将日期字段绑定到具有 2 列的“值列表”组合框?