WPF DataGrid with a one click ComboBox showing enumeration values sorted by enumeration names
Requirements
I would like to add a column with comboboxes to a WPF DataGrid meeting the following requirements:
- The value displayed in the ComboBox should be the name of the enumeration constant
- The entries in the ComboBox should be sorted by the name of the enumeration constant
- The property type in the underlying object should be enum, not string
- The number of clicks should be reduced. When I use DataGridComboBoxColumn, I need about 4 clicks to change a value.
- I actually like code behind solutions, although XAML based solutions are fine too.
- It should run under .NET 5 WPF
Sample Application
The application uses the code provided in the DataGridComboBoxColumn. It works, but has 2 problems:
-
the Details DropDown lists the entries alphabetically. In my real application I have many more entries and it is very difficult to find the right one when they are not sorted.
-
It takes 4 mouse clicks to change a ComboBox value.
Code
XAML:
<Window x:Class="SortedComboBoxDataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SortedComboBoxDataGrid"
xmlns:core="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Window.Resources>
<CollectionViewSource x:Key="SamplesViewSource" CollectionViewType="ListCollectionView"/>
<ObjectDataProvider x:Key="myEnum" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type Type="local:DetailEnum"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<DataGrid x:Name="MainDataGrid" DataContext="{StaticResource SamplesViewSource}" ItemsSource="{Binding}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=SomeText}" Header="SomeText"/>
<DataGridComboBoxColumn Header="Detail" SelectedItemBinding="{Binding Detail}"
ItemsSource="{Binding Source={StaticResource myEnum}}"/>
</DataGrid.Columns>
</DataGrid>
</Window>
Enum DetailEnum:
namespace SortedComboBoxDataGrid {
public enum DetailEnum {
No,
Some,
Many,
All
}
Sample class:
public class Sample {
public string SomeText { get; set; }
public DetailEnum Detail { get; set; }
public Sample(string someText, DetailEnum detail) {
SomeText = someText;
Detail = detail;
}
}
}
Window code behind:
using System.Collections.Generic;
using System.Windows;
namespace SortedComboBoxDataGrid {
public partial class MainWindow: Window {
public MainWindow() {
InitializeComponent();
var samples = new List<Sample>() {
new Sample("first", DetailEnum.All),
new Sample("second", DetailEnum.Many),
new Sample("any", DetailEnum.Some),
new Sample("last", DetailEnum.No),
};
var samplesViewSource = ((System.Windows.Data.CollectionViewSource)(FindResource("SamplesViewSource")));
samplesViewSource.Source = samples;
}
}
}
What I have tried already
I tried Displaying sorted enum values in a ComboBox. This sorts enums nicely, but to do so it converts the enum values into strings, then sorts those strings. If the user clicks on a different entry, the grid returns a string and not an enumeration value.
I tried various solutions I found on stackoverflow to reduce the number of tricks, but could not get one working properly with sorted (!) enums.
I wonder if it would be better to use for the ComboBox a list of class instances having the enum value and the enum name as its properties instead of a List ?
public class DetailEnumClass {
public DetailEnum EnumValue { get; set; }
public string EnumName { get; set; }
}
Please read this before marking this question as a duplicate
I am aware there are already many answers on stackoverflow regarding one or the other problem I mentioned here. However, I am not able to come up with a working solution which covers all requirements. So please only mark this question as a dupplicate if you have found an answer which provides full code for the complete problem. Thanks.
from Recent Questions - Stack Overflow https://ift.tt/2YB7Acz
https://ift.tt/3v3T0GF
Comments
Post a Comment