using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using JD.Filters;
using Xceed.Wpf.DataGrid;
namespace JD.Pickers.PickerControls
{
///
/// http://stackoverflow.com/questions/1329362/c-sharp-generics-usercontrol
/// The C# compiler does not support Generics inheriting from UserControl, so we need to "hide" the generic in an intermediate class.
///
public partial class MultiPicker : UserControl
{
}
///
/// Interaction logic for MultiPicker.xaml
///
public class MultiPicker : MultiPicker
{
private readonly ICollectionView _collectionViewDataList;
private readonly ICollectionView _collectionViewSelectionList;
// keyboard keys you can use to select/deselect a map
private readonly List _selectKeys = new List { Key.Space, Key.Right };
private readonly List _deselectKeys = new List { Key.Space, Key.Delete, Key.Left };
private ObservableCollection DataList { get; }
public ObservableCollection Selection { get; }
public Filter Filter { get; set; }
public MultiPicker(IEnumerable items)
{
InitializeComponent();
DataList = new ObservableCollection();
Selection = new ObservableCollection();
// populate
foreach (var item in items)
{
DataList.Add(item);
}
// configure filter
Filter = new Filter(typeof(T))
{
HasQuickFilter = true,
RefreshAction = () => { _collectionViewDataList.Refresh(); }
};
_collectionViewDataList = CollectionViewSource.GetDefaultView(DataList);
_collectionViewDataList.Filter = Filter.Apply;
_collectionViewSelectionList = CollectionViewSource.GetDefaultView(Selection);
filterControl.Filter = Filter;
// databinding
dataGridControl.DataContext = DataList;
dataGridControl.ItemsSource = DataList;
selectedListControl.ItemsSource = Selection;
// link events
buttonSelect.Click += SelectEvent;
buttonDeselect.Click += DeselectEvent;
selectedListControl.KeyUp += DeselectKeyEvent;
dataGridControl.KeyUp += SelectKeyEvent;
// events for listbox items
var style = new Style(typeof(ListBoxItem));
style.Setters.Add(new EventSetter(MouseDoubleClickEvent,
new MouseButtonEventHandler(DeselectEvent)));
selectedListControl.ItemContainerStyle = style;
// events for datarow items
style = new Style(typeof(DataRow));
style.Setters.Add(new EventSetter(MouseDoubleClickEvent,
new MouseButtonEventHandler(SelectEvent)));
dataGridControl.ItemContainerStyle = style;
/* disable listbox spacebar selection (so that the spacebar can be used as we want) */
selectedListControl.PreviewKeyDown += (sender, e) =>
{
if (e.Key == Key.Space)
{
e.Handled = true;
}
};
dataGridControl.Loaded += SetColumnWidth;
}
private void SetColumnWidth(object sender, RoutedEventArgs e)
{
const int minWidth = 150;
var totalControlWidth = dataGridControl.ActualWidth;
var numberOfColumns = dataGridControl.Columns.Count;
foreach (var column in dataGridControl.Columns)
{
column.Width = Math.Max(totalControlWidth / numberOfColumns, minWidth);
}
}
private void DeselectEvent(object sender, RoutedEventArgs e)
{
RemoveSelectedViewFromSelection();
}
private void DeselectKeyEvent(object sender, KeyEventArgs e)
{
if (_deselectKeys.Contains(e.Key))
{
RemoveSelectedViewFromSelection();
}
}
private void SelectEvent(object sender, RoutedEventArgs e)
{
AddSelectedRowsToSelection();
}
private void SelectKeyEvent(object sender, KeyEventArgs e)
{
if (_selectKeys.Contains(e.Key))
{
AddSelectedRowsToSelection();
}
}
private void AddSelectedRowsToSelection()
{
var selectedItems = dataGridControl.SelectedItems;
foreach (T member in selectedItems)
{
if (!Selection.Contains(member))
{
Selection.Add(member);
}
}
dataGridControl.SelectedItems.Clear();
}
private void RemoveSelectedViewFromSelection()
{
while (selectedListControl.SelectedIndex != -1)
{
var element = selectedListControl.SelectedItem;
Selection.Remove((T)element);
}
_collectionViewSelectionList.Refresh();
}
public bool? ShowDialog(Window owner = null)
{
var dialogWindow = new Window
{
Content = this,
WindowStyle = WindowStyle.ToolWindow,
HorizontalContentAlignment = HorizontalAlignment.Stretch,
VerticalContentAlignment = VerticalAlignment.Stretch,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Width = 750,
Owner = owner,
Topmost = true
};
dialogWindow.Loaded += (sender, e) => filterControl.SearchBox.Focus();
buttonOk.Click += (sender, e) => { dialogWindow.DialogResult = true; };
buttonCancel.Click += (sender, e) => { dialogWindow.DialogResult = false; };
// keyboard shortcuts
dialogWindow.KeyUp += (sender, e) =>
{
if (e.Key == Key.Return)
{
dialogWindow.DialogResult = true;
}
else if (e.Key == Key.Escape)
{
dialogWindow.DialogResult = false;
}
};
return dialogWindow.ShowDialog();
}
}
}