未对集合更新ListBox与ObservableCollection的绑定

时间:2016-09-21 13:38:51

标签: wpf xaml observablecollection

我有下一个型号:

public class MyModel
{
    public ObservableCollection<MyObject> MyList {get; set;}
}

public class MyObject
{
   MyObservableDictionary MyDictionary {get; set;}
}

public class  MyObservableDictionary : ObservableCollection<EnymValue>
{
}

public class EnymValue : INotifyPropertyChanged
{
  private MyEnum key;
    private string value;

    public MyEnum Key
    {
        get
        {
            return this.key;
        }
        set
        {
            this.key = value;
            NotifyPropertyChanged("Key");
        }
    }
    public string Value
    {
        get
        {
            return this.value;
        }
        set
        {
            this.value = value;
            NotifyPropertyChanged("Value");
        }
    }

    public LanguageValue(MyEnum key, string value)
    {
        this.Key = key;
        this.Value = value;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public enum MyEnum
{
}

在View上我有一个ListBox:

<ListBox x:Name="MyList" SelectionMode="Single" ItemsSource="{Binding Path=MyList, Mode=OneWay}">
     <ListBox.ItemTemplate>
        <DataTemplate>
             <TextBlock Text="{Binding Path=MyDictionary, Mode=OneWay, Converter={StaticResource myEnumToTextConverter}}" />
         </DataTemplate>
      </ListBox.ItemTemplate>
</ListBox>

(myEnumToTextConverter转换器只是从集合中选择第一个元素并返回它的值,或者如果集合为空或空则返回一些指定的常量)

我希望在更改任何EnymValue值时,可以在视图上更新我的模型列表框。 有可能以某种方式实现这个吗?

目前,Value更改后视图未更新。 我试图从EnymValue继承INotifyPropertyChanged,但这并没有帮助。在更新属性时,在PropertyChanged == null上看起来像EnymValue.NotifyPropertyChanged

2 个答案:

答案 0 :(得分:2)

ObservableCollection能够在更改集合本身(添加或删除元素)时通知UI有关更改的信息。但是ObservableCollection并不知道修改其中某个项目时发生的更改。要解决此问题,您可以订阅CollectionChange可观察集合事件,并在添加新项目时订阅新项目的PropertyChanged。引发PropertyChanged事件时,您可以在列表上触发通知OnPropertyChanged(()=>MyItems);您应该小心实现此解决方案并记住取消订阅事件以避免内存泄漏。

我在this answer中可以看到的一个例子。

答案 1 :(得分:0)

您的MyDictionary应该强制刷新。最简单的方法是重新分配其旧值,并在MyObject中实现INPC,如下所示:

public class MyObject: INotifyPropertyChanged
    {
        MyObservableDictionary _myDictionary;
        public MyObservableDictionary MyDictionary {
            get
            {
                return _myDictionary;
            }
            set
            {
                _myDictionary = value;
                OnPropertyChanged("MyDictionary");
            }
        }

        public MyObject()
        {
            MyDictionary = new MyObservableDictionary();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string prop)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }

更改值的示例代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    // vm is ViewModel instance, vm is DataContext set for Window

    var old = vm.MyList[0].MyDictionary;
    vm.MyList[0].MyDictionary[0].Value = "aaaa";
    vm.MyList[0].MyDictionary = old;
}

我对此进行了测试,并将更改后的值显示为“aaaa”。

相关问题