wpf ComboBox异步绑定到项目源问题

时间:2009-07-10 18:13:32

标签: wpf mvvm combobox

我有一个mvvm应用程序,主窗口是一个选项卡控件。 我使用itemssource将项绑定到组合框, 一切正常,直到我去另一个标签,由于某种原因组合框的选定项目获得空值,任何想法?

绑定是twoway updatesource onpropertychanged,属性是observablecollection的类型

5 个答案:

答案 0 :(得分:2)

之前我遇到过同样的问题。解决方案是确保在SelectedValue属性之前未声明XAML中comboBox的Itemsource属性。它应该工作。

答案 1 :(得分:2)

只需要处理ObservableCollection并仅加载为AddRange(不使用'Add')

当我们将数据加载为:

foreach (object item in items)
{
    MyList.Add(item); // Where MyList is a ObservableCollection
}

然后在添加第一个元素后,ObservableCollection调用OnCollectionChanged。 然后ComboBox将尝试选择SelectedValue并在找不到此元素时返回'null'。

它可以解决问题:

using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;

namespace System.Collections.ObjectModel
{
    /// <summary> 
    /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public class ObservableCollectionEx<T> : ObservableCollection<T>
    {
        /// <summary> 
        /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. 
        /// </summary> 
        public ObservableCollectionEx()
            : base() { }

        /// <summary> 
        /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. 
        /// </summary> 
        /// <param name="collection">collection: The collection from which the elements are copied.</param> 
        /// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception> 
        public ObservableCollectionEx(IEnumerable<T> collection)
            : base(collection) { }

        /// <summary> 
        /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). 
        /// </summary> 
        public void AddRange(IEnumerable<T> collection)
        {
            //
            // Add the items directly to the inner collection
            //
            foreach (var data in collection)
            {
                this.Items.Add(data);
            }

            //
            // Now raise the changed events
            //
            this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));

            this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

    }
}

答案 2 :(得分:0)

我有一个mvvm应用程序,几乎完全相同的情况。主窗口有一个选项卡控件。有一个包含组合框的标签。组合框项目源绑定到IList(在视图模型中),并且Selected值绑定到实现INotifyPropertyChanged的视图模型中的属性。

<ComboBox ItemsSource="{Binding AllowedJudges}"  
                  SelectedValue="{Binding SelectedJudge, UpdateSourceTrigger=PropertyChanged}"  >

选择另一个选项卡时,视图模型绑定到SelectedValue的属性会神秘地设置为null。我能够通过不允许将SelectedValue-bound属性设置为null来处理它:

 public Judge SelectedJudge
  {
     get { return selectedJudge; }
     set
     {
        if(selectedJudge==value || value==null) return;
        selectedJudge = value;
        OnPropertyChanged("SelectedJudge");
        updateViewData();
     }
  }

但是,我不清楚为什么一个标签窗格变得不可见意味着组合框中的值会被取消选择....

答案 3 :(得分:0)

如果由于某种原因,ItemsSource的BindingSource不再包含SeletedItem(因为它已重新初始化或其他),则SelectedItem可以重置为默认值,即null。 从你的例子中我不知道为什么会发生这种情况,但这可能是因为你错过了添加更多的环境代码。

答案 4 :(得分:0)

这可能是你的viewmodel ierarchy的问题。  例如,如果Binding的两端都是依赖项属性,并且ownertype属性未绑定到特定类(例如,设置父类),则所有继承器将一起使用此依赖项属性。糟糕的设计