views:

69

answers:

1

I have a user control containing a listbox. I want to bind to the listboxes selected item property so I created a dependency property.

        public HousePrice SelectedItem
        {
        get 
        { 
            return (HousePrice)GetValue(SelectedItemProperty); 
        }
        set
        {
            SetValue(SelectedItemProperty, value);
        }
    }

    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register(
            "SelectedItem",
            typeof(HousePrice),
            typeof(HorizontalListBox),
            null
        );

    private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count > 0)
        {
            SelectedItem = (HousePrice)e.AddedItems[0];
        }
    }

I bind to the property like this:

   <UserControls:HorizontalListBox
   DataContext="{Binding HousePrices}"
       SelectedItem="{Binding SelectedPriceFrom, Mode=TwoWay}" >
   </UserControls:HorizontalListBox>

My view model property:

        private HousePrice _selectedPriceFrom;
    public HousePrice SelectedPriceFrom
    {
        get
        {
            return _selectedPriceFrom;
        }
        set
        {
            _selectedPriceFrom = value;
            NotifyOfPropertyChange("SelectedPriceFrom");
        }
    }

I can see the dp being set but the binding to my vm property does not seem to work.

Edit:

I think the problem is to do with the DataContext for the UserControl being set to HousePrices (one property in my VM) and SelectedItem being set to another property in my VM. I'm guessing that it is trying to find SelectedItem relative to HousePrices.

Another quirk is that I'm using the Caliburn Micro framework.

Any ideas?

A: 

Now fixed.

I added another dependency property for ItemsSource and made sure I wired up all the DP property changed events to the user control properties.

Here is how the user control was used:

    <UserControls:HorizontalListBox
       ItemsSource="{Binding PriceFromList}"
       SelectedItem="{Binding SelectedPriceFrom, Mode=TwoWay}">
    </UserControls:HorizontalListBox>

and here is how I wired up the DPs:

    /// <summary>
    /// Item Source
    /// </summary>
    public ObservableCollection<ObjWithDesc> ItemsSource
    {
        get 
        {
            return (ObservableCollection<ObjWithDesc>)GetValue(ItemsSourceProperty); 
        }
        set
        {
            SetValue(ItemsSourceProperty, value);
        }
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(
            "ItemsSource",
            typeof(ObservableCollection<ObjWithDesc>),
            typeof(HorizontalListBox),
            new PropertyMetadata(OnItemsSourcePropertyChanged)
        );

    static void OnItemsSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        ((HorizontalListBox) obj).OnItemsSourcePropertyChanged(e);
    }

    private void OnItemsSourcePropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        ObservableCollection<ObjWithDesc> objWithDescList = (ObservableCollection<ObjWithDesc>)e.NewValue;

        MainListBox.ItemsSource = objWithDescList;
    }

    /// <summary>
    /// Selected Item
    /// </summary>
    public ObjWithDesc SelectedItem
    {
        get
        {
            return (ObjWithDesc)GetValue(SelectedItemProperty);
        }
        set
        {
            SetValue(SelectedItemProperty, value);
        }
    }

    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register(
            "SelectedItem",
            typeof(ObjWithDesc),
            typeof(HorizontalListBox),
            new PropertyMetadata(OnSelectedItemPropertyChanged)
        );

    static void OnSelectedItemPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        ((HorizontalListBox)obj).OnSelectedItemPropertyChanged(e);
    }

    private void OnSelectedItemPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        ObjWithDesc selectedItem = (ObjWithDesc)e.NewValue;

        MainListBox.SelectedItem = selectedItem;
    }

    private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count > 0)
        {
            SelectedItem = (ObjWithDesc)e.AddedItems[0];
        }
    }
SteveChadbourne