Search code examples
c#wpfmvvmbindingdependency-properties

Why is my Dependency Property Binding is not working as expected?


I am trying to make a customized UserControl which includes a ListView. I would like to bind the SelectedItem Property to my View Model. I therefore created a DP in my User Control and bound the SelectedItem Property of the ListView to the new Dependency Property.

        public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
            "SelectedItem",
            typeof(object), 
            typeof(DragAndDropListView),
            new PropertyMetadata(SelectedItemPropertyChangedCallback));

        private static void SelectedItemPropertyChangedCallback(DependencyObject d, 
        DependencyPropertyChangedEventArgs e)
        {
            if (d is DragAndDropListView dragAndDropListView)
            {
            }
        }

        public object SelectedItem
        {
            get => GetValue(SelectedItemProperty);
            set => SetValue(SelectedItemProperty, value);
        }

In the xaml code I then made a binding

            <ListView Name="ListView"
                      PreviewMouseLeftButtonDown="ListViewPreviewMouseLeftButtonDown"
                      AllowDrop="True"
                      MouseMove="ListViewMouseMove"
                      DragEnter="ListViewDragEnter"
                      Drop="ListViewDrop"
                      SelectedItem="{Binding Path= SelectedItem}"/>

And to make sure it works I assigned the UserControl as DataContext to the ListView

        public DragAndDropListView()
        {
            InitializeComponent();
            ListView.ItemsSource = Items;
            ListView.DataContext = this;
        }

And then I added a binding where I use the UserControl.

       <userControls:DragAndDropListView 
                Items="{Binding SelectedCustomers}" 
                SelectedItem="{Binding SelectedCustomer}"
                DisplayMemberPath="Name"
                Grid.Column="0"
                Grid.Row="0"/>

As you may see I thought, that I don't need a SelectedItemPropertyChangedCallback. First I didn't even implement it. I added it later to add a break point to see if it even works. When I select an item in the listView it calls the callback. But the setter of the SelectedCustomer in my ViewModel is never called.

I would expect this to work. Please help me to understand my mistake.


Solution

  • The Binding must be TwoWay:

    SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"
    

    You could declare the property so that it binds TwoWay by default:

    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register(
            nameof(SelectedItem),
            typeof(object), 
            typeof(DragAndDropListView),
            new FrameworkPropertyMetadata(
                null,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                SelectedItemPropertyChangedCallback));