将 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