Заполнение выпадающего списка из ViewModel или Model в datagrid

#c# #wpf

#c# #wpf

Вопрос:

Привет, у меня здесь есть таблица данных:

 <DataGrid   CanUserResizeRows="False" VerticalAlignment="Top" Margin="0,10,80,0" Grid.Column="0" Grid.RowSpan="3" Grid.ColumnSpan="3" HorizontalAlignment="Center" Grid.Row="1" CanUserAddRows="False" AutoGenerateColumns="False" HeadersVisibility="All">
            <DataGrid.Columns>

                <!-- Combobox-->
                <materialDesign:DataGridComboBoxColumn HeaderStyle="{StaticResource DGHeader}" Header="Part Number"  ItemsSource="{x:Static model:ViewModel.EpicorParts}"/>

                <!--TextBox Column-->
                <materialDesign:DataGridTextColumn HeaderStyle="{StaticResource DGHeader}" Header="Description" Binding="{Binding Description}" ElementStyle="{StaticResource MaterialDesignDataGridTextColumnStyle}" EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>

                <!--Combobox Column-->
                <materialDesign:DataGridComboBoxColumn HeaderStyle="{StaticResource DGHeader}" Header="Reason Code"/>

                <materialDesign:DataGridComboBoxColumn HeaderStyle="{StaticResource DGHeader}" Header="Qty"/>

                <!--Numeric Column -->
                <DataGridTemplateColumn Header="BOM" HeaderStyle="{StaticResource DGHeader}" CellTemplate="{StaticResource ButtonColumn}"/>
            </DataGrid.Columns>
        </DataGrid>
 

Итак, разные ObservableCollections заполняют разные области здесь, но для начала у меня есть модель:

 public EpicorParts(SqlDataReader reader)
        {
            Part = reader.GetString("PartNum");
            Desc = reader.GetString("PartDescription");
            partClass = reader.GetString("ClassID");
        }

        private string _Part;
        public string Part
        {
            get { return _Part; }
            set { _Part = value; RaisePropertyChanged("PartNum"); }
        }

        private string _Desc;
        public string Desc
        {
            get { return _Desc; }
            set { _Desc = value; RaisePropertyChanged("PartDescription"); }
        }

        private string _partClass;
        public string partClass
        {
            get { return _partClass; }
            set { _partClass = value; RaisePropertyChanged("ClassID"); }
        }
 

Я хотел бы заполнить part number столбец с PartNum помощью и Description столбец с Desc помощью Я пытался использовать источник элемента, как вы видите в столбце со списком, но это больше не позволяет мне вставлять. Не позволит мне сделать ItemsSource="{x:Static model:ViewModel.EpicorParts.Part}"

На всякий случай, если это необходимо, вот viewmodel

 public static ObservableCollection<EpicorParts> EpicorParts { get; set; } = new ObservableCollection<EpicorParts>();

public static void GetEpicorParts()
        {
            EpicorParts.Clear();
            using var conn = new SqlConnection(Settings.Default.Epicor2Connection);

            conn.Open();
            string qry = "SELECT PartNum, PartDescription, ClassID from Erp.part where ClassID='slnc' and InActive = 1";
            var cmd = new SqlCommand(qry, conn);

            var reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                EpicorParts.Add(new EpicorParts(reader));
            }
            conn.Close();
        }
 

Надеюсь, я прояснил, что я пытаюсь сделать.

Комментарии:

1. Вы хотите ViewModel.EpicorParts заполнить параметры в выпадающем списке или во всей таблице данных? И откуда Items берется в первой строке вашего фрагмента кода?

2. @arconaut извините Items , что там не должно быть. Я просто хочу, чтобы параметры заполняли столбец 0 и столбец 1 выпадающего списка

Ответ №1:

Во-первых, я полагаю, что с вашей viewmodel есть некоторые проблемы. Вы запускаете изменение свойства с помощью «partNum» для двух свойств. Обратите внимание на свои свойства:

 public class EpicorPart // or better even EpicorPartViewModel, since you're binding to it
{
    // ...
    public string PartNum
    {
        get { return _part; }
        set { 
            _part = value;
            RaisePropertyChanged(nameof(PartNum)); } // what's used here should match the property name, it's easy to keep this consistent with `nameof()`
        }

    // also, you use 'Desc' here, but 'Description' in the grid...

 

Далее, если я правильно понимаю проблему, вам нужно привязать ItemsSource вашу сетку данных к EpicorParts свойству вашей ViewModel.

Затем каждый столбец может быть привязан к одному из свойств EpicorPart класса:

 <DataGrid ItemsSource="{x:Static model:ViewModel.EpicorParts}" >    
   ... columns come here, see below
</DataGrid>
 

Чтобы отобразить значение ‘Part Number’ в столбце выпадающего списка, привяжите SelectedItemBinding свойство к этому свойству EpicorPart . ItemsSource of DataGridComboBoxColumn предназначен для хранения доступных параметров в этом выпадающем списке (список, который вы видите, когда выпадающий список открыт). Поэтому вы должны привязать его к этому списку. Не уверен, что это уже существует, но это может выглядеть примерно так:

 <materialDesign:DataGridComboBoxColumn 
    Header="Part Number" 
    SelectedItemBinding="{Binding PartNum}"         ---> this is for what is being displayed as 'selected' in the combobox
    ItemsSource="{Binding AvailablePartNumbers}" /> ---> not sure if you have it, but the point is - it's probably a separate list

<materialDesign:DataGridTextColumn 
    Header="Description" 
    Binding="{Binding Description}"   --> here this should work already, as long as the whole grid is bound to the ObservableCollection
    />

 

Комментарии:

1. Итак, когда я устанавливаю ItemSource DataGrid значение, оно заполняет его всеми этими строками, когда мне нужно только 5 максимальных строк. Я не хочу заполнять DataGrid , а просто materialDesign:DataGridComboBoxColumn

2. Извините, мне трудно понять, что именно вы хотите создать…

3. Я понятия не имею, как я мог бы объяснить более честно. Все, что я хочу сделать, это заполнить ComboBox в datagrid, А НЕ в datagrid. Я хочу заполнить с помощью модели EpicorParts , привязать Part к одному ComboBoxColumn из них и привязать Desc к текстовому столбцу рядом с ним.