ListBox mouse selection.
How can I implement selection with mouse in ListBox control?
I want similar selection as in Outlook calendar.
Thanks.
Answers
I've mocked up with a sample of how to enable this type of selection mode for ListBox control, you can refactor the sample into a UserControl or custom control. Here is the code:
Code Block<ListBox Name="listBox" Width="200" Height="200" BorderBrush="Navy" BorderThickness="1" SelectionMode="Multiple">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="ListBoxItem.PreviewMouseLeftButtonDown" Handler="ListBoxItem_PreviewMouseLeftButtonDown"/>
<EventSetter Event="ListBoxItem.PreviewMouseUp" Handler="ListBoxItem_PreviewMouseUp"/>
<EventSetter Event="ListBoxItem.PreviewMouseMove" Handler="ListBoxItem_PreviewMouseMove"/>
</Style>
</ListBox.Resources>
<x:Type TypeName="DependencyObject"/>
<x:Type TypeName="Visual"/>
<x:Type TypeName="UIElement"/>
<x:Type TypeName="FrameworkElement"/>
<x:Type TypeName="Control"/>
</ListBox>
public partial class Window1 : Window
{
private Boolean inMouseSelectionMode = false;
private List<ListBoxItem> selectedItems = new List<ListBoxItem>();
public Window1()
{
InitializeComponent();
}
private void ListBoxItem_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
inMouseSelectionMode = false;
}
private void ListBoxItem_PreviewMouseMove(object sender, MouseEventArgs e)
{
ListBoxItem mouseOverItem = sender as ListBoxItem;
if (mouseOverItem != null && inMouseSelectionMode && e.LeftButton == MouseButtonState.Pressed)
{
mouseOverItem.Background = SystemColors.HighlightBrush;
mouseOverItem.SetValue(TextElement.ForegroundProperty, SystemColors.HighlightTextBrush);
if (!selectedItems.Contains(mouseOverItem))
{
selectedItems.Add(mouseOverItem);
}
}
}
private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
listBox.SelectedIndex = -1;
inMouseSelectionMode = true;
foreach (ListBoxItem item in selectedItems)
{
item.ClearValue(ListBoxItem.BackgroundProperty);
item.ClearValue(TextElement.ForegroundProperty);
}
selectedItems.Clear();
}
}
Hope this helps
All Replies
Well, could you please elaborate a bit about the type of scenario you want to enable? ListBox has already implemented the mouse selection, do you want to enable something beyond that?
Thanks
- Thanks for reply.
Yes, I need more complex selection, like in the Outlook calendar. That is, I click the item, drag the mouse and all items inside the mouse rectangle are selected.
Listbox has similar selection but it can be made only using the Shift key.
Thanks. I've mocked up with a sample of how to enable this type of selection mode for ListBox control, you can refactor the sample into a UserControl or custom control. Here is the code:
Code Block<ListBox Name="listBox" Width="200" Height="200" BorderBrush="Navy" BorderThickness="1" SelectionMode="Multiple">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="ListBoxItem.PreviewMouseLeftButtonDown" Handler="ListBoxItem_PreviewMouseLeftButtonDown"/>
<EventSetter Event="ListBoxItem.PreviewMouseUp" Handler="ListBoxItem_PreviewMouseUp"/>
<EventSetter Event="ListBoxItem.PreviewMouseMove" Handler="ListBoxItem_PreviewMouseMove"/>
</Style>
</ListBox.Resources>
<x:Type TypeName="DependencyObject"/>
<x:Type TypeName="Visual"/>
<x:Type TypeName="UIElement"/>
<x:Type TypeName="FrameworkElement"/>
<x:Type TypeName="Control"/>
</ListBox>
public partial class Window1 : Window
{
private Boolean inMouseSelectionMode = false;
private List<ListBoxItem> selectedItems = new List<ListBoxItem>();
public Window1()
{
InitializeComponent();
}
private void ListBoxItem_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
inMouseSelectionMode = false;
}
private void ListBoxItem_PreviewMouseMove(object sender, MouseEventArgs e)
{
ListBoxItem mouseOverItem = sender as ListBoxItem;
if (mouseOverItem != null && inMouseSelectionMode && e.LeftButton == MouseButtonState.Pressed)
{
mouseOverItem.Background = SystemColors.HighlightBrush;
mouseOverItem.SetValue(TextElement.ForegroundProperty, SystemColors.HighlightTextBrush);
if (!selectedItems.Contains(mouseOverItem))
{
selectedItems.Add(mouseOverItem);
}
}
}
private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
listBox.SelectedIndex = -1;
inMouseSelectionMode = true;
foreach (ListBoxItem item in selectedItems)
{
item.ClearValue(ListBoxItem.BackgroundProperty);
item.ClearValue(TextElement.ForegroundProperty);
}
selectedItems.Clear();
}
}
Hope this helps
Thanks a lot, Marco.
Great! Thanks Marco!


