Home > Back-end >  How to use DataGridComboBoxColumn in C# project?
How to use DataGridComboBoxColumn in C# project?

Time:07-18

I'm facing some issues with my C# WPF project and, especially, the DataGridComboBoxColumn control. So, here's a part of my MainWindow.xaml file :

<DataGrid x:Name="WorkDayGrid"
          AutoGenerateColumns="False"
          CanUserAddRows="False"
          CanUserDeleteRows="False"
          CanUserSortColumns="False"
          ItemsSource="{Binding}">
    <DataGrid.Resources>
        <local:Times x:Key="times" />
        <local:TimeConverter x:Key="timeConverter" />
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridComboBoxColumn Header="Arrival Time"
                                ItemsSource="{StaticResource times}"
                                SelectedItemBinding="{Binding ArrivalTime, Converter={StaticResource timeConverter}}" />
    </DataGrid.Columns>
</DataGrid>

And the corresponding "code-behind" :

public partial class MainWindow : Window
{
    private ObservableCollection<WorkDay> _workDays = new ObservableCollection<WorkDay>();

    public MainWindow()
    {
        InitializeComponent();

        ComputeWorkDays();
        WorkDayGrid.DataContext = _workDays;
    }

    private void ComputeWorkDays()
    {
        _workDays.Clear();

        for (var i = 1; i <= 31;   i)
        {
            var d = new WorkDay();
            _workDays.Add(d);
        }
    }
}

The code of the WorkDay class :

class WorkDay
{
    public Time ArrivalTime { get; set; }
}

The code of the Times class :

class Times : ObservableCollection<Time>
{
    public Times()
    {
        var firstHour = 7;
        var lastHour = 20;
        var minuteStep = 5;

        for (var i = firstHour; i < lastHour;   i)
        {
            for (var j = 0; j < 60; j  = minuteStep)
            {
                var t = new Time
                {
                    Hour = i,
                    Minute = j
                };
                Add(t);
            }
        }
    }
}

The code of the Time class :

class Time
{
    private int _hour = 0;
    private int _minute = 0;

    public int Hour
    {
        set => _hour = value;
    }
    public int Minute
    {
        set => _minute = value;
    }

    public override string ToString()
    {
        var fmt = "D2";
        return _hour.ToString(fmt)   ":"   _minute.ToString(fmt);
    }
}

The code of the TimeConverter class :

class TimeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            var time = (Time)value;
            return time.ToString();
        }
        else
        {
            string result = "";
            return result;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (Time)value;
    }
}

The problem is when I select a value in one cell (thanks to the related combo box), the same value is also displayed in another cell. In addition, when I scroll down to another row in the data grid, the selected value disappears. I wonder if the DataGridComboBoxColumn works well... I use the .NET framework 4.6.1. Thank you very much for your help.

CodePudding user response:

At the end of the day, it was the binding converter which caused the issue. Thank you @Clemens for your help.

FYI, I don't use the DateTime struct because I need an "invalid" time to allow the user to cancel its selection.

  • Related