0

I don't know if I'm the first to ask this question(I searched the whole board) but I never found any answers. As said in the title I am trying to highlight/select an item in my Listbox whenever I right click it.

Here is the XAML code:

<ListBox Grid.Row="1" x:Name="ContactList" Margin="6" ItemsSource="{Binding ''}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Status_Image}" Margin="0,0,3,0" />
                <StackPanel Orientation="Vertical">
                    <TextBlock Height="20" HorizontalAlignment="Left" Text="{Binding Name}" FontWeight="Bold" FontSize="13" Foreground="Black" />
                    <TextBlock Height="20" HorizontalAlignment="Left" Text="{Binding Message}" FontSize="11" Foreground="Gray" />
                </StackPanel>
    <Image Source="{Binding NotifImg}" Margin="8,0,0,0"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

I know how to handle right click and show a Context menu on a button or a single element, but not on a bound Listbox. If you have any advices on how I should proceed please feel free to tell me because I'm currently stuck.

Thank you, Ephismen.

Aymeric
  • 1,324
  • 3
  • 15
  • 33
  • Have you seen this link? http://stackoverflow.com/questions/3115892/right-click-on-a-listbox-in-a-silverlight-4-app Though it does discuss about context menu, I think it may be useful in some way – Mamta D Oct 04 '10 at 15:56
  • Yes I have seen that link, but it doesn't provide the information I need since no one answered his questions. – Aymeric Oct 04 '10 at 15:58
  • I'd simply create behavior (or trigger/action combo) and attach it to the top stack panel. – Denis Oct 04 '10 at 20:11
  • Yes but how can I select a UI element with right click? the Listbox has a default LeftClick event enabled, but the right click is not native and so it doesn't select anything when I trigger it. – Aymeric Oct 04 '10 at 20:54
  • Set SelectedItem property of ListBox to the item that recived right click – Denis Oct 05 '10 at 04:29
  • This is exactly the meaning of my question: I don't know how to know which item received right click. – Aymeric Oct 05 '10 at 07:29

2 Answers2

1

Alright I found a very simple and clean way of achieving what I wanted to do!

Here is the XAML code:

<ListBox Grid.Row="1" x:Name="ContactList"ItemsSource="{Binding ''}" MouseRightButtonDown="ContactList_MouseRightButtonDown" MouseRightButtonUp="ContactList_MouseRightButtonUp">
     <ListBox.ItemTemplate>
         <DataTemplate>
             <StackPanel Orientation="Horizontal" >
                 <TextBlock Height="20" HorizontalAlignment="Left" Text="{Binding Name}" FontWeight="Bold" FontSize="13" Foreground="Black" />
                 <TextBlock Height="20" HorizontalAlignment="Left" Text="{Binding Message}" FontSize="11" Foreground="Gray" />
                 <Image Source="{Binding NotifImg}" Margin="8,0,0,0"/>
             </StackPanel>
         </DataTemplate>
     </ListBox.ItemTemplate>
</ListBox>

And the code behind:

    private void ContactList_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        e.Handled = true;
    }

    private void ContactList_MouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), (sender as ListBox)).OfType<ListBoxItem>().First().IsSelected = true;
    }    

Don't forget to include System.Linq for the 'OfType'.

Ephismen.

Aymeric
  • 1,324
  • 3
  • 15
  • 33
0

Multiselection mode solution

The solution from Ephismen above does not work correctly for a ListBox in multiselection mode (e.g. it doesn't toggle item's selected state when Ctrl is down, it does not deselect other items when Ctrl is not down, ...).

I would suggest to create a custom ListBoxItem instead, with a custom right mouse click handler. There you can simulate a left mouse button click and thus get exactly the same behavior:

public class CustomListBoxItem : ListBoxItem
{
    protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
    {
        OnMouseLeftButtonDown(e);
    }
}

You may also need to create a simple converter for the ItemsSource binding - to replace the standard ListBoxItem, which would be created by default, by your CustomListBoxItem:

public class ItemsToCustomListBoxItemsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return null;

        return
            from object item in (IEnumerable) value
            select new CustomListBoxItem
                {
                    Content = item
                };
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new InvalidOperationException();
    }
}

And here's how the ItemsSource binding would look like:

<ListBox
    ...
    ItemsSource="{Binding Converter={StaticResource ItemsToCustomListBoxItemsConverter}}"
    ...>