using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Data;
namespace Plugin.Views.Controls
{
public interface ISelectDialogOption
{
object Key { get; }
string Label { get; set; }
object Value { get; }
}
public class SelectDialogOption<TKey, TValue> : ISelectDialogOption
{
public SelectDialogOption(TKey key, string label, TValue value)
{
Key = key;
Label = label;
Value = value;
}
public TKey Key { get; set; }
public string Label { get; set; }
public TValue Value { get; set; }
object ISelectDialogOption.Key => Key;
object ISelectDialogOption.Value => Label;
}
public partial class SelectDialog : Window
{
public SelectDialog(string question, string title)
{
InitializeComponent();
Loaded += new RoutedEventHandler(SelectDialog_Loaded);
txtQuestion.Text = question;
Title = title;
}
private CollectionView ListView => (CollectionView)CollectionViewSource.GetDefaultView(lvDetails?.ItemsSource);
public void InitOptions<TKey, TValue>(IEnumerable<SelectDialogOption<TKey, TValue>> options, TKey defaultValue = default(TKey)) where TKey : class
{
lvDetails.ItemsSource = options;
ListView.Filter = CustomFilter;
var selectedItem = options.FirstOrDefault(x => x.Key == defaultValue);
if (selectedItem?.Key != null)
lvDetails.SelectedItem = selectedItem;
}
private bool CustomFilter(object item)
{
if (string.IsNullOrEmpty(txtFilter.Text)) return true;
if (item is ISelectDialogOption option)
return Search(GetSearchWords(txtFilter.Text), option.Label);
return false;
}
public static bool Search(List<string> words, string label) => words.All(x => label.IndexOf(x, StringComparison.OrdinalIgnoreCase) >= 0);
public static List<string> GetSearchWords(string text) => text.Trim().Split(' ').Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
public static TValue ShowSelectDialog<TKey, TValue>(string question, string title, IEnumerable<SelectDialogOption<TKey, TValue>> options, TKey defaultValue = default(TKey)) where TKey : class
{
var inst = new SelectDialog(question, title);
inst.InitOptions(options, defaultValue);
inst.ShowDialog();
if (inst.DialogResult == true && inst.SelectedItem is SelectDialogOption<TKey, TValue> kv)
return kv.Value;
return default;
}
private void BtnOk_Click(object sender, RoutedEventArgs e)
{
if (SelectedItem == null) return;
DialogResult = true;
Close();
}
public object SelectedItem => lvDetails.SelectedItem;
void SelectDialog_Loaded(object sender, RoutedEventArgs e) => txtFilter.Focus();
private void BtnCancel_Click(object sender, RoutedEventArgs e) => Close();
private void txtFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) => ListView.Refresh();
}
}
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x:Class="Plugin.Views.Controls.SelectDialog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="CenterScreen"
SizeToContent="WidthAndHeight"
MinWidth="400"
MinHeight="100"
WindowStyle="SingleBorderWindow"
ResizeMode="CanMinimize">
<StackPanel Margin="5">
<TextBlock Name="txtQuestion" Margin="5"/>
<TextBox DockPanel.Dock="Top" Margin="0,0,0,10" Name="txtFilter" TextChanged="txtFilter_TextChanged" />
<ListView Name="lvDetails" Height="200">
<ListView.View>
<GridView>
<GridViewColumn Header=" " Width="400" DisplayMemberBinding="{Binding Label}" />
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right">
<Button Content="_OK" IsDefault="True" Margin="5" Name="BtnOk" Click="BtnOk_Click" />
<Button Content="_Cancel" IsCancel="True" Margin="5" Name="BtnCancel" Click="BtnCancel_Click" />
</StackPanel>
</StackPanel>
</Window>
Example:
var options = lookup.InventoryItems.Select(x => new SelectDialogOption<string, CommonInvItemClient>(x.Item, $"{x.GTIN} {x.Name} ({x.Item})", x)).OrderBy(x => x.Label);
var invItem = SelectDialog.ShowSelectDialog("Zoek artikel (of GTIN) en selecteer om aan de orderregel te koppelen", "Artikel matchen", options);
if (invItem == null) return;
var invItemGTIN = invItem.GTIN ?? invItem.EAN;747200cookie-checkXAML SelectDialog