Click here to Skip to main content
15,846,091 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Project subject: I had an MS Access 2003 adp VBA project that would connect to SQL Server Database, Now I'm converting that project to C# WPF, and I'm going to save data directly into SQL Server database from DataGrid in C# WPF

Detail: I have DataGrid that ItemsSource binds to an 'ObservableCollection' named: 'INVO_DATA_RASID_KHARID' and also 'DataGridComboBoxColumn' named: 'ANBAR_COLUMN' the 'ItemSource' of this 'DataGridComboBoxColumn' is filled through SQL Server.

I want this 'DataGridComboBoxColumn' to be displayed with a default value so that the user knows that there is no need to manually select it from the 'DataGridComboBoxColumn' list.

I set this default value through a static variable in code behind in this method named: 'FillALLComboboxes'.

enter image description here
[^]


The Problem: Considering that 'DataGridComboBoxColumn' in the DataGrid, the 'ANBAR_COL' 'DataGridComboBoxColumn' has a default value, the user does not need to select that item manually from the 'DataGridComboBoxColumn' list, but as long as they double-click on the 'ANBAR_COL' combobox cell, the default value It will appear! The point is that the default value set for 'DataGridComboBoxColumn' will not be displayed until the user enters the cell!

https://i.stack.imgur.com/UL1gU.png

What I have tried:

XAML :

        <DataGrid   x:Name="INVO_LST_RASID_SUB"
                        EnableColumnVirtualization="True"
                        EnableRowVirtualization="True"
                        VirtualizingPanel.IsVirtualizing="True"
                        VirtualizingPanel.VirtualizationMode="Recycling"
                        ScrollViewer.CanContentScroll="False"
                    
                        KeyboardNavigation.TabNavigation="Contained"
                        ItemsSource="{Binding INVO_DATA_RASID_KHARID}"
                        Grid.Row="5"
                        Margin="5,10"
                        AutoGenerateColumns="False"  FlowDirection="RightToLeft"  SelectionUnit="FullRow"   BorderThickness="1" >
       
            <DataGrid.Columns>

                <DataGridComboBoxColumn x:Name="ANBAR_COLUMN" MinWidth="80" Width="auto" Header=" انبار " 
                                        SelectedValueBinding="{Binding ANBAR,UpdateSourceTrigger=PropertyChanged}"
                                        DisplayMemberPath="NAMES" SelectedValuePath="CODE">
                    <DataGridComboBoxColumn.EditingElementStyle>
                        <Style TargetType="{x:Type ComboBox}">
                            <Setter Property="IsEditable" Value="True"/>
                        </Style>
                    </DataGridComboBoxColumn.EditingElementStyle>

                </DataGridComboBoxColumn>
       
            </DataGrid.Columns>
        </DataGrid>


Code behind of my Window (C#):

//MainWindow:
    public partial class HEAD_LST_RASID : Window
    {
        public ObservableCollection<INVO_LST_RASID_KHARID_CSHARP> INVO_DATA_RASID_KHARID { get; set; } = new ObservableCollection<INVO_LST_RASID_KHARID_CSHARP>();

        public HEAD_LST_RASID()
        {
            InitializeComponent();
            this.DataContext = this;
        }
        public void FillALLComboboxes()
        {
            string RowSource_ANBAR = "SELECT    CODE, NAMES FROM  dbo.TCOD_ANBAR";
            //Search for the default value if it exists
            var rst = dbms.Database.SqlQuery<int?>("SELECT     ANBCO FROM dbo.OPANBACCESS WHERE     (USERCO = " + Baseknow.USERCOD + " ) ORDER BY dbo.OPANBACCESS.RDF").ToList();
            if (rst.Count > 0)
            {
                Baseknow.anbardef = (int)rst.FirstOrDefault();
            }
            var ARST = dbms.Database.SqlQuery<Custom_TCODANBAR>(RowSource_ANBAR).ToList();
            ANBAR_COLUMN.ItemsSource = ARST;
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            FillALLComboboxes();
            
              var QRE_LST = dbms.Database.SqlQuery<INVO_LST_RASID_KHARID_CSHARP>($@"SELECT * FROM INVOICES").ToList();
              INVO_DATA_RASID_KHARID?.Clear();
              
                foreach (var item in QRE_LST)
                    INVO_DATA_RASID_KHARID.Add(item);
        }
    }
Model Class :

//Model:
    public class CTABLES
    {
        public class INVO_LST_RASID_KHARID_CSHARP : INotifyPropertyChanged, ICloneable
        {
            public object Clone()
            {
                return this.MemberwiseClone();
            }
        
            public INVO_LST_RASID_KHARID_CSHARP()
            {
                ANBAR = Baseknow.anbardef;
            }

            private int? _anbar;
            public int? ANBAR
            {
                get
                {
                    return _anbar;
                }
                set
                {
                    if (_anbar == value)
                        return;
                    _anbar = value;
                    OnPropertyChanged("ANBAR");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


What I want is to show that a default value has been selected for this combobox inside the 'DataGrid' when the 'DataGrid' data is loaded (without the need to double-click and go to CellEditing mode).
Posted
Updated 2-May-23 12:28pm
Comments
Gerry Schmitz 2-May-23 16:45pm    
By default, most "selector" controls default to .SelectedIndex == -1 (empty set or nothing selected); so, you should set the index if it makes a difference (after loading).
mojtabahakimian 2-May-23 17:05pm    
How can I set SelectedIndex for the 'DataGridComboBoxColumn' dynamically ? (Binding)

1 solution

When I hit an issue, sometimes I like to remove the noise and break out a small project that focuses on the main issue. I have done just that for you.

Start a new WPF project with the name WpfDataGridComboBox and drop this code in and you can see how it works.

1. MainWindow.xaml
XML
<Window x:Class="WpfDataGridComboBox.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        x:Name="Window1">

    <Grid DataContext="{Binding ElementName=Window1}">
        <Grid.Resources>
            <CollectionViewSource x:Key="ChoicesCVS"
                                  Source="{Binding Choices}" />
        </Grid.Resources>

        <DataGrid AutoGenerateColumns="False"
                  ItemsSource="{Binding Items}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name"
                                    Binding="{Binding Name}" />
                <DataGridTextColumn Header="Age"
                                    Binding="{Binding Age}" />
                <DataGridComboBoxColumn
                    Header="Mode" Width="100" 
                    SelectedItemBinding="{Binding Choice}"
                    ItemsSource="{Binding Source={StaticResource ChoicesCVS}}">
                </DataGridComboBoxColumn>
            </DataGrid.Columns>
            
        </DataGrid>
    </Grid>

</Window>


2. the code behind file MainWindow.xaml.cs
C#
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;

namespace WpfDataGridComboBox
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public List<string> Choices { get; set; } = new()
        {
            "Choice 1",
            "Choice 2",
            "Choice 3"
        };

        public ObservableCollection<Person> Items { get; set; } = new()
        {
            new() { Name = "Freddie", Age = 21, Choice = "Choice 1" },
            new() { Name = "Milly", Age = 18, Choice = "Choice 2" },
            new() { Name = "Caddie", Age = 23, Choice = "Choice 3" },
        };
    }

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Choice { get; set; }
    }
}

Now run the project and it will perform as expected. Now you can take this and apply to your own code.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900