将 ObservableCollection 绑定到 WPF 列表框

Posted

技术标签:

【中文标题】将 ObservableCollection 绑定到 WPF 列表框【英文标题】:Binding ObservableCollection to WPF ListBox 【发布时间】:2011-05-07 13:01:07 【问题描述】:

我有以下代码隐藏:

    public partial class MainWindow : Window
    
        public MainWindow()
        
            InitializeComponent();
        

        ObservableCollection<int> sampleData = new ObservableCollection<int>();
        public ObservableCollection<int> SampleData
        
            get
            
                if (sampleData.Count <= 0)
                
                    sampleData.Add(1);
                    sampleData.Add(2);
                    sampleData.Add(3);
                    sampleData.Add(4);
                
                return sampleData;
            
        
    

我的 xaml 是:

<Window x:Class="Sandbox.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 ItemsSource="Binding Path=SampleData"/>
    </Grid>
</Window>

列表不显示集合中的值(或任何内容)。谁能指出我的错误是什么?

我需要明确设置 DataContext 吗?我想如果没有设置,控件只会将自己用作 DataContext。

【问题讨论】:

显式设置DataContext是否有效? 【参考方案1】:

尝试使用 MvvM 模式,以便在视图中定义 ListBox,如下所示:

<ListBox ItemsSource="Binding Path=Log, UpdateSourceTrigger=PropertyChanged"/>

那么View就可以不用绑定源代码了。在相关的 ViewModel 中添加如下内容:

public class ViewModel : ViewModelBase

    //...
    private ObservableCollection<string> p_Log;

    /// <summary>
    /// A log of a starting process
    /// </summary>
    public ObservableCollection<string> Log
    
        get  return p_Log; 

        set
        
            base.RaisePropertyChangingEvent("Log");
            p_Log.Add(value.ToString());
            base.RaisePropertyChangedEvent("Log");
        
    
    //....
    /// <summary>
    /// Initializes this view model.
    /// </summary>
    /// <param name="mainWindowViewModel">The view model for this application's main window.</param>
    private void Initialize(MainWindowViewModel mainWindowViewModel)
      
        //...
        p_Log = new ObservableCollection<string>();
    

然后在 ViewModelBase 中定义的事件将保持 View 中的绑定更新,而无需在任何时候将新字符串添加到可观察集合 p_log 中的任何代码。

【讨论】:

【参考方案2】:

我通常在构造函数中传入一个视图模型,并将数据上下文设置为传入的视图模型。然后可以将您的 ObservableCollection 移出视图并放入视图模型中。这将您的视图与逻辑分开,还允许您对视图模型代码进行单元测试。

public MainWindow(SomeViewModel viewModel) 
 
    DataContext = viewModel;

    InitializeComponent(); 
 

【讨论】:

【参考方案3】:

是的,您需要以某种方式设置 DataContext。它没有 DataContext,因为 Window 没有 DataContext,除非它被设置。如果您在构造函数中执行此操作,ListBox 将获取 DataContext。

public MainWindow() 
 
    InitializeComponent(); 
    this.DataContext = this;
 

否则你可以在 Binding 中使用 RelativeSource、ElementName 等,但我猜你知道 =)

【讨论】:

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

将 ObservableCollection 绑定到 WPF 列表框

如何将 ObservableCollection 绑定到 DataTemplate 中的文本框?

如何将 ObservableCollection 与 datagrid WPF 绑定

如何将 WPF DataGrid 绑定到 ObservableCollection

Xamarin.Forms 无法通过 ViewModel 将 ObservableCollection 绑定到 CollectionList

我应该绑定到 ICollectionView 还是 ObservableCollection