nikhil
nikhil

Reputation: 1748

Binding to dependency property in a ViewModel

I have dependency property in SliderViewModel where this view model implements DependencyObject and is set as the data context for BRSliderUserControl. How can I bind to the dependency property in the view model from AmplitudeOptionsUserControl. Is it possible to do so. My guess is I need to create an other dependency property in BRSliderUserControl and then send the update value to the view model. Is this the right way though?

SliderViewModel.cs

public Class SliderViewModel:DependencyObject
{
    public AnalysisViewType AnalysisTypeValue
            {
                get { return (AnalysisViewType)GetValue(AnalysisTypeDependencyProperty); }
                set { SetValue(AnalysisTypeDependencyProperty, value); }
            }


            public static readonly DependencyProperty AnalysisTypeDependencyProperty =
                DependencyProperty.Register("AnalysisTypeValue", typeof(AnalysisViewType), typeof(SliderViewModel),
                    new PropertyMetadata(AnalysisViewType.Unassigned, OnAnalysisTypeChanged));

            private static void OnAnalysisTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                //Do something here
            }
}

BRSliderUserControl.xaml.cs

  public BRSliderUserControl()
            {
                InitializeComponent();
                SliderViewModel sliderViewModel = new SliderViewModel();
                this.DataContext = sliderViewModel;
            }

Now how can I bind to that dependency property from another user control?

AmplitudeOptionsControl.xaml

//This does not work..

    <lib:BRSliderUserControl
                    Grid.Row="5"
                    Grid.Column="0"
                    Grid.ColumnSpan="3"
                    AnalysisTypeValue="{Binding AmplitudeOptionsVM.AnalysisType,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
                 />

Upvotes: 0

Views: 5184

Answers (2)

mm8
mm8

Reputation: 169400

Move the dependency property to the code-behind of the UserControl class:

public class BRSliderUserControl
{
    public AnalysisViewType AnalysisTypeValue
    {
        get { return (AnalysisViewType)GetValue(AnalysisTypeDependencyProperty); }
        set { SetValue(AnalysisTypeDependencyProperty, value); }
    }

    public static readonly DependencyProperty AnalysisTypeDependencyProperty =
        DependencyProperty.Register("AnalysisTypeValue", typeof(AnalysisViewType), typeof(BRSliderUserControl),
            new PropertyMetadata(AnalysisViewType.Unassigned, OnAnalysisTypeChanged));

    private static void OnAnalysisTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //Do something here
    }

    public BRSliderUserControl()
    {
        InitializeComponent();
        SliderViewModel sliderViewModel = new SliderViewModel();
        this.DataContext = sliderViewModel;
    }
}

Add a plain CLR property to the view model:

public class SliderViewModel : INotifyPropertyChanged
{
    private AnalysisViewType _analysisTypeValue;
    public AnalysisViewType AnalysisTypeValue
    {
        get { return _analysisTypeValue; }
        set { _analysisTypeValue = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Bind the dependency property in the view to the source property of the view model:

<lib:BRSliderUserControl
                Grid.Row="5"
                Grid.Column="0"
                Grid.ColumnSpan="3"
                AnalysisTypeValue="{Binding AnalysisTypeValue}" />

Upvotes: 2

user3188639
user3188639

Reputation:

You don't need dependency property in your View Models. Your ViewModel should implement INotifyPropertyChanged interface, and your properties should raise NotifyPropertyChanged event when the value changes. There are many helpers around which makes this a bit easier.

You can use Dependency property if you want, but it makes your view models dependent on WPF, although binding to Dependency properties seems to be much faster (see here: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-data-binding)

You can see a discussion here: INotifyPropertyChanged vs. DependencyProperty in ViewModel

Also, since your DataContext is of type SliderViewModel, which has a public property named AnalysisTypeValue, in your XAML you should bind like this

... AnalysisTypeValue = {Binding AnalysisTypeValue}

Upvotes: 2

Related Questions