【问题标题】:PropertyChanged Event handler is always null also with OneWay specificationPropertyChanged 事件处理程序始终为空,也具有 OneWay 规范
【发布时间】:2018-02-03 03:08:00
【问题描述】:

我在 XAML 中创建了一个简单的 ListView,它应该绑定到 ObservablaCollection:

<PivotItem x:Uid="pvItemMusic" Header="Music">
            <StackPanel>
                <TextBlock Name="tbSelectMusicHeader" Text="Select directories that should be included into your library" FontSize="18" Margin="20"></TextBlock>
                <Button Name="btnSelectSourcePath" Content="Add path" Margin="30,10,0,10" Click="btnSelectSourcePath_Click"></Button>
                <ListView Name="lvPathConfiguration" DataContext="{StaticResource configurationVM}" ItemsSource="{Binding MusicBasePathList, Mode=OneWay}">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <RelativePanel>
                                <TextBlock Name="tbPath" Text="{Binding Mode=OneWay}" RelativePanel.AlignTopWithPanel="True" VerticalAlignment="Center" Width="400" Margin="20"></TextBlock>
                                <Button Name="btnRemovePath" x:Uid="btnRemovePath" Content="Remove" RelativePanel.RightOf="tbPath" Margin="10" Height="48"></Button>
                            </RelativePanel>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackPanel>
        </PivotItem>

我的 ViewModel 的命名空间是由

导入的
xmlns:applicationVM="using:Crankdesk.CrankHouseControl.ViewModel.Application"

我添加了我的 ViewModel 的页面资源:

<Page.Resources>
        <applicationVM:ConfigurationViewModel x:Key="configurationVM"></applicationVM:ConfigurationViewModel>
    </Page.Resources>

btnSelectSourcePath 应该将路径添加到存储在 ViewModel 中的源路径列表中,这将在 CodeBehind 中完成:

private async void btnSelectSourcePath_Click(object sender, RoutedEventArgs e)
        {
            FolderPicker picker = new Windows.Storage.Pickers.FolderPicker();
            picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;
            picker.FileTypeFilter.Add("*");

            StorageFolder folder = await picker.PickSingleFolderAsync();

            if (folder != null)
            {
                // Save path to configuration
                App.ConfigurationViewModel.MusicBasePathList.Add(folder.Path);
            }
        }

在 ViewModel 中使用了“INotifyPropertyChanged”事件,我使用 ObersableCollection 的“CollectionChanged”事件来触发 PropertyChanged 事件。当我在调试模式下添加路径时,将执行 RaisePropertyChanged 方法,但“处理程序”属性始终为 NULL。

private void RaisePropertyChanged(string propertyName)
        {

            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

这是我的整个 ViewModel:

namespace Crankdesk.CrankHouseControl.ViewModel.Application
{
    public class ConfigurationViewModel : INotifyPropertyChanged
    {    
        private ObservableCollection<string> _musicBasePathList;

        public ObservableCollection<string> MusicBasePathList
        {
            get
            {
                return _musicBasePathList; 
            }
            set
            {
                _musicBasePathList = value;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public ConfigurationViewModel()
        {
            _musicBasePathList = new ObservableCollection<string>();
            _musicBasePathList.CollectionChanged += _musicBasePathList_CollectionChanged;
        }

        private void _musicBasePathList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {   
            RaisePropertyChanged(nameof(MusicBasePathList));
        }


        private void RaisePropertyChanged(string propertyName)
        {

            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

我在这里做错了什么?我知道我在这里第 34 次问这个问题,但我没有找到解决方案。在大多数情况下,他们忘记指定 OneWay 或 TwoWay,但这里不是这种情况。

提前谢谢....

戴夫

【问题讨论】:

  • 而ViewModel的代码在哪里?
  • 如果没有可靠地重现问题的良好minimal reproducible example,就不可能知道实际答案是什么。但是,我保证它最终会成为您的数据绑定实现中的一些简单错误。最有可能的两个候选者是:数据上下文设置不正确,或者您的模型类具有PropertyChanged 事件但实际上并未声明为实现INotifyPropertyChanged。 (如果你确实改进了你的帖子并添加了一个好的minimal reproducible example,请在你写的时候仔细检查并修复所有的拼写错误和拼写错误……草率的问题不太可能引起注意。)
  • 你是对的。我编辑了我的帖子并添加了 ViewModel....
  • 当集合内容发生变化时,不需要在 MusicBasePathList 上引发 PropertyChanged,因为它是同一个集合,它不会在视图上做任何事情。但是你应该在 MusicBasePathList 的设置器中提出 PropertyChanged
  • 我不这么认为。当我只是将一些东西添加到集合中时,将永远不会调用 setter。当我创建一个新的 Collection 并将其写入 MusicBasePathList 时,将调用 setter。

标签: c# mvvm uwp inotifypropertychanged


【解决方案1】:

您的应用程序中至少有 两个 ConfigurationViewModel 实例。

  1. App.ConfigurationViewModel
  2. 在页面资源中定义为configurationVM

视图绑定到 2. 实例,并在后面的代码中修改 1. 实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-03
    • 2016-09-16
    • 1970-01-01
    • 2017-12-12
    • 2014-06-15
    • 2013-07-17
    • 1970-01-01
    相关资源
    最近更新 更多