ObservableCollection上的WPF UserControl DependencyProperty和INotifyPropertyChanged

时间:2014-03-18 20:40:23

标签: c# wpf mvvm

在尝试MVVM实现时,我有一个实现INotifyPropertyChanged的UserControl。似乎在FilePaths具有新值后调用OnFilePathsChanged,因此它只是将其复制。如果我没有实现INotifyPropertyChanged OnPropertyChanged,则VIEWMODEL永远不会更新。我已经读过,使用INotifyPropertyChanged和DependencyProperty是多余的,但我无法找到最佳方法。我错过了什么有没有更简洁的方法来实现带有绑定ObservableCollection的UserControl?

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;            }
    }

1 个答案:

答案 0 :(得分:1)

关于你实际上询问的内容有点不清楚,但我认为无论你问什么,这都会对你有所帮助。如果您有一个绑定到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 ...至少,在DependencyProperty中声明UserControl更为习惯。但是,如果您已声明要在UserControl中绑定数据的正常CLR属性,那么 也应在那里实现INotifyPropertyChanged接口。