【问题标题】:Binding ObservableCollection to WPF ListBox将 ObservableCollection 绑定到 WPF 列表框
【发布时间】: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是否有效?

标签: wpf wpf-controls binding


【解决方案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 等,但我猜你知道 =)

      【讨论】:

        猜你喜欢
        • 2012-05-30
        • 2018-08-13
        • 1970-01-01
        • 2010-12-08
        • 1970-01-01
        • 2017-09-29
        • 1970-01-01
        • 1970-01-01
        • 2011-08-28
        相关资源
        最近更新 更多