WPF UserControl DependencyProperty and INotifyPropertyChange

本文关键字:INotifyPropertyChange and DependencyProperty UserControl WPF | 更新日期: 2023-09-27 17:50:54

在一个尝试的MVVM实现中,我有一个UserControl实现INotifyPropertyChanged。OnFilePathsChanged似乎在fileppaths有了新值之后被调用,所以它只是再次复制它。如果我不实现INotifyPropertyChanged OnPropertyChanged的VIEWMODEL从未得到更新。我读到使用INotifyPropertyChanged与DependencyProperty一起是多余的,但我无法找出最好的方法来做到这一点。我错过了什么?是否有一个更干净的方法来实现一个绑定ObservableCollection的UserControl ?

用户控件代码
private void LoadFileMenuItem_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog dialog = new OpenFileDialog();
        if (dialog.ShowDialog() == true)
        {
            FilePaths.Add(dialog.FileName);
            OnPropertyChanged("FilePaths");
        }
    }
 private void InitFilePathsProperty()
    {
        this.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(FilePaths_PropertyChanged);
    }
    void FilePaths_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        this.SetValue(FilePathsProperty, ImageFilePaths);
    }
    public static readonly DependencyProperty FilePathsProperty = DependencyProperty.Register("FilePaths", typeof(ObservableCollection<string>), typeof(FileDisplayControl),
                new PropertyMetadata(OnImageFilePathsChanged));
    private static void OnFilePathsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue != null)
        {
            var myFileDisplayControl = obj as FileDisplayControl;
            if (myFileDisplayControl != null &&
                myFileDisplayControl.FilePaths != null)
            {
                FilePaths = this.GetValue(args.Property) as ObservableCollection<string>;
            }
        }
    }
    public ObservableCollection<string> FilePaths
    {
        get { return this.GetValue(FilePathsProperty) as ObservableCollection<string>;  }
        set { this.SetValue(FilePathsProperty, value); }
    }

在VIEWMODEL

    public ObservableCollection<string> ViewModelFilePaths
    {
        get            {                return _viewModelFilePaths;            }
        set            {                _viewModelFilePaths = value;            }
    }

WPF UserControl DependencyProperty and INotifyPropertyChange

对于你实际上问什么有点不清楚,但我认为这将帮助你无论你问什么。如果你有一个视图模型是数据绑定到UserControl.DataContext的,你仍然可以使用RelativeSource Binding绑定到该控件中定义的任何DependencyProperty。以 UserControl中的

为例:

绑定UserControl DependencyProperty:

<ListBox ItemsSource="{Binding FilePaths, RelativeSource={RelativeSource 
    AncestorType={x:Type YourPrefix:YourUserControl}}}" ... />

绑定到数据绑定视图模型属性:

<ListBox ItemsSource="{Binding ViewModelFilePaths}" ... />

你应该在视图模型中实现INotifyPropertyChanged接口,而不是UserControl…至少,更习惯的做法是在UserControl中声明DependencyProperty。但是,如果您已经声明了希望在UserControl中进行数据绑定的普通CLR属性,那么您也应该在那里实现INotifyPropertyChanged接口。