none
ListBox ItemTemplate and Selected Item

    Question

  • I have a standard listbox with and item template and I am trying to conform to the MVVM pattern.

     <ListBox ItemsSource="{Binding View}" IsSynchronizedWithCurrentItem="True" ItemTemplate="{StaticResource editable}">
               
     </ListBox>

    The template has some textboxes and checkboxes on them. But I am having trouble with a hyperlink that is also on the template. The hyperlink is bound to a comand for deletion. When I click the hyperlink the command fires, but the currentitem is always the first element in the listbox. I need a way, when somone clicks into a control that the selecteditem changes. I have tired using a trigger for mousover, but cannot get back to the listitem that the template is apllied to.

    Wednesday, June 10, 2009 1:17 PM

Answers

  • Here is what i did.

       private void Hyperlink_Click(object sender, RoutedEventArgs e)
            {
                ListBox ep = FindControl<ListBox>(this);
                ep.SelectedItem = DataContext;
            }

            T FindControl<T>(DependencyObject ep) where T:DependencyObject
            {
                DependencyObject p = VisualTreeHelper.GetParent(ep);

                if (p == null) return null;

                T parent = p as T;

                if (parent != null)
                    return parent;
                return FindControl<T>(p);
            }

    it breaks the mvvm model a little.. but it's the only way I could find to do what I needed.
    • Marked as answer by spunkyvt Thursday, June 11, 2009 12:43 PM
    Thursday, June 11, 2009 12:43 PM

All replies

  • A ListBox wraps each data item in a container (ListBoxItem). That container handles the selected presentation. But the ListBox will also set the DataContext of that container to the data item.
    So, if you get a MouseOver event, the sender will probably be some UIElement inside the container, but it's DataContext property should contain the data item you are looking for (inherited from the container's DataContext).

    hth,
    Marcel
    Thursday, June 11, 2009 7:25 AM
  • Here is what i did.

       private void Hyperlink_Click(object sender, RoutedEventArgs e)
            {
                ListBox ep = FindControl<ListBox>(this);
                ep.SelectedItem = DataContext;
            }

            T FindControl<T>(DependencyObject ep) where T:DependencyObject
            {
                DependencyObject p = VisualTreeHelper.GetParent(ep);

                if (p == null) return null;

                T parent = p as T;

                if (parent != null)
                    return parent;
                return FindControl<T>(p);
            }

    it breaks the mvvm model a little.. but it's the only way I could find to do what I needed.
    • Marked as answer by spunkyvt Thursday, June 11, 2009 12:43 PM
    Thursday, June 11, 2009 12:43 PM
  • I haven't used mvvm much yet, but if you want to follow that better, I think your viewmodel needs a SelectedItem property. You can bind the SelectedItem of the ListBox to that property.
    Then in your Hyperlink_Click handler you can set the viewmodel's SelectedItem to the hyperlink's DataContext and the databinding will then update the ListBox's SelectedItem. That way you don't need to search the visual tree...

    hth,
    Marcel
    Thursday, June 11, 2009 2:00 PM