简体   繁体   English

绑定到 ObservableCollection 的列表框不会更新

[英]Listbox bound to an ObservableCollection doesn't update

I am using a ObservableCollection to store the Environment Variables of Windows.我正在使用 ObservableCollection 来存储 Windows 的环境变量。

class VariableVieWModel
{
    ObservableCollection<VariableModel> vars;

    public ObservableCollection<VariableModel> Variables
    {
        get
        {
            return vars;
        }
        set
        {
            vars = value;
        }
    }

    public VariableViewModel() 
    {
        Reload();
    }

    public void Reload()
    {
    // Code to retrieve vars
    }
}

This ObservableCollection is bound to a ListBox.此 ObservableCollection 绑定到 ListBox。

I have added a button in the GUI to reload the Variables whichi, on click, it calls the Reload() procedure.我在 GUI 中添加了一个按钮来重新加载变量,点击它,它会调用 Reload() 过程。

ListBox content, however, does not change and I cannot add anymore items to the list afer calling Reload().然而,ListBox 的内容并没有改变,在调用 Reload() 之后,我无法再向列表中添加项目。

Under the constructor everything is working fine.在构造函数下一切正常。

ListBox XAML:列表框 XAML:

<ListBox x:Name="lbVariables" Grid.Column="0" Margin="0,0,5,0" ItemsSource="{Binding Source={StaticResource variablesViewModel}, Path=Variables}" IsSynchronizedWithCurrentItem="True"> 

I tried using also PropertyChanged as UpdateSource trigger and set most of the Modes.我也尝试使用 PropertyChanged 作为 UpdateSource 触发器并设置大多数模式。

public void Reload()
    {
        vars = new ObservableCollection<VariableModel>();

        RegistryKey systemVarKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment");

        string[] systemVars = systemVarKey.GetValueNames();

        foreach (string var in systemVars)
        {
            vars.Add(new VariableModel()
            {
                Name = var,
                Values = (systemVarKey.GetValue(var, null, RegistryValueOptions.DoNotExpandEnvironmentNames) as string).Split(';').ToList<string>(),
                Target = EnvironmentVariableTarget.Machine
            });
        } 
        systemVarKey.Close();

        RegistryKey userVarKey = Registry.CurrentUser.OpenSubKey(@"Environment");

        string[] userVars = userVarKey.GetValueNames();

        foreach (string var in userVars)
        {
            vars.Add(new VariableModel()
            {
                Name = var,
                Values = (userVarKey.GetValue(var, null, RegistryValueOptions.DoNotExpandEnvironmentNames) as string).Split(';').ToList<string>(),
                Target = EnvironmentVariableTarget.User
            });
        }
        userVarKey.Close();
    }

You haven't modified the ObservableCollection, only replaced it.您没有修改 ObservableCollection,只是替换了它。 You should implement INotifyPropertyChanged and call PropertyChanged in the Variables property setter.您应该实现INotifyPropertyChanged并在Variables属性设置器中调用PropertyChanged

BTW it's common in MVVM implementations to have a base class for your ViewModel:顺便说一句,在 MVVM 实现中,为您的 ViewModel 提供一个基本 class 是很常见的:

class VariableViewModel : ViewModelBase

and implement common functionality such as INotifyPropertyChanged in the base class to avoid duplication of code.并在基础 class 中实现INotifyPropertyChanged等常用功能,以避免重复代码。

You need to implement INotifyPropertyChanged for your VariableVieWModel to refresh your target object bindings.您需要为您的 VariableVieWModel 实现INotifyPropertyChanged以刷新您的目标 object 绑定。 You just have to do this way -你只需要这样做 -

class VariableVieWModel : INotifyPropertyChanged
    { .
      .
            public ObservableCollection<VariableModel> Variables
            {
               get
               {
                  return vars;
               }
               set
               {
                  if(vars!=value)
                  {
                      vars = value;
                      OnPropertyChanged("Variables");
                  }
               }
            }

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

The problem is, that probably your VariableModel does not implement INotifyPropertyChanged .问题是,您的 VariableModel 可能没有实现INotifyPropertyChanged Through ObservableCollection, only changes to the collection are reported, not changes of the contained objects.通过 ObservableCollection,只报告集合的变化,而不是包含对象的变化。

Here you will find some implementation possibilities. 在这里你会发现一些实现的可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM