jitusurve Ответов: 1

Двусторонняя привязка WPF datagrid: добавить строку при нажатии кнопки


Я новичок в WPF. Я уже неделю борюсь за то, чтобы добавить строку в datagrid одним нажатием кнопки.

Мой DataGrid привязан к
ObservableCollection<FilterCriteria> FilterCriteriaList


Извините за добавление кода такой длины. Будучи новичком в WPF, я не уверен, чего именно мне здесь не хватает. Поэтому стараюсь предоставить как можно больше информации

Это мой класс параметр filtercriteria

public class FilterCriteria : INotifyPropertyChanged
    {
        private NORTHWNDEntities context = new NORTHWNDEntities();

        private string columnName;
        public string ColumnName
        {
            get
            {
                return columnName;
            }
            set
            {
                columnName = value;
                RaisePropertyChanged("ColumnName");
            }
        }

        private string _operator;
        public string Operator
        {
            get
            {
                return _operator;
            }
            set
            {
                _operator = value;
                RaisePropertyChanged("Operator");
            }
        }

        private string inputValue;
        public string InputValue
        {
            get
            {
                return inputValue;
            }
            set
            {
                inputValue = value;
                RaisePropertyChanged("InputValue");
            }
        }

        private string selectedTable;
        public string SelectedTable
        {
            get
            {
                return selectedTable;
            }
            set
            {
                selectedTable = value;
                RaisePropertyChanged("SelectedTable");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged([CallerMemberName]string propertyName = "")
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


Это мой код ViewModel

public class ExportTablesViewModel : INotifyPropertyChanged
    {
        private NORTHWNDEntities context = new NORTHWNDEntities();

        private ObservableCollection<DatabaseTable> tableNameList;
        public ObservableCollection<DatabaseTable> TableNameList
        {
            get
            {
                return tableNameList;
            }
            set
            {
                tableNameList = value;
                RaisePropertyChanged("TableNameList");
            }
        }

        private ObservableCollection<string> selectedTableColumnList;

        public ObservableCollection<string> SelectedTableColumnList
        {
            get
            {
                return selectedTableColumnList;
            }
            set
            {
                selectedTableColumnList = value;
                RaisePropertyChanged("SelectedTableColumnList");
            }
        }


        private ObservableCollection<FilterCriteria> filterCriteriaList;

        public ObservableCollection<FilterCriteria> FilterCriteriaList
        {
            get
            {
                return filterCriteriaList;
            }
            set
            {
                filterCriteriaList = value;
                RaisePropertyChanged("FilterCriteriaList");
            }
        }


        private string selectedTableName;

        public string SelectedTableName
        {
            get
            {
                return selectedTableName;
            }
            set
            {
                selectedTableName = value;
                RaisePropertyChanged("SelectedTableName");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged([CallerMemberName]string propertyName = "")
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


Это код xaml для сетки:

<DataGrid x:Name="dataGridFilters" CanUserAddRows="True"  ItemsSource="{Binding FilterCriteriaList}" AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="313,31,0,0" VerticalAlignment="Top" Height="261" Width="679">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Column">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="ComboBoxColumnName" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SelectedTableColumnList}" 
                                      SelectedValue="{Binding Path=ColumnName,Mode =TwoWay,UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True}" SelectedValuePath="ColumnName"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Operator">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox x:Name="TextBoxOperator" Text="{Binding Path=Operator,Mode =TwoWay,UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Value">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox x:Name="TextBoxInputValue" Text="{Binding Path=InputValue,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="buttonAddFilter" Content="+" HorizontalAlignment="Left" Margin="958,76,0,0" VerticalAlignment="Top" Width="34" RenderTransformOrigin="0.5,0.5" Click="buttonAddFilter_Click">
        </Button>


При нажатии на кнопку Я пытаюсь добавить строку в сетку. Для этого я добавляю viewModel.FilterCriteriaList.Добавить(новый параметр filtercriteria()); в buttonAddFilter_Click событие. Этот код добавляется как новая строка в datagrid. Но когда я ввожу какое-то значение во вновь добавленную строку. Он не добавляется в коллекцию FilterCriteriaList

Пожалуйста, дайте мне знать, как сделать двустороннюю привязку для вновь добавленной строки?

Что я уже пробовал:

уже объяснено в вопросе, например, как я определил модель представления, ObservableCollection, код xaml

1 Ответов

Рейтинг:
0

J. Calhoun

Во-первых, вам не нужно поднимать свойство, измененное с помощью наблюдаемой коллекции, оно встроено. Во-вторых, вы должны избегать использования ключевого слова "new" при привязке к наблюдаемой коллекции, потому что это нарушает привязку. Наблюдаемые коллекции поднимают свойство, измененное на событиях clear() и add (), так что

1) объявите, что вы связали наблюдаемую коллекцию один раз

public ObservableCollection<FilterCriteria> FilterCriteriaList { get; set; }


Затем в вашем конструкторе вы можете создать экземпляр.
public ExportFiltersViewModel() 
{ 
   FilterCriteriaList = new ObservableCollection<FilterCriteriaList>(); 
};


Далее, на ваш взгляд, вы не показываете двусторонний
<DataGrid x:Name="dataGridFilters" CanUserAddRows="True"  ItemsSource="{Binding FilterCriteriaList, Mode="Two-Way" }"


Теперь вот где вы должны посмотреть свойства ICommand, чтобы привязать событие нажатия кнопки к вашей модели представления, чтобы оно выглядело примерно так
<Button x:Name="buttonAddFilter" Content="+" HorizontalAlignment="Left" Margin="958,76,0,0" VerticalAlignment="Top" Width="34" RenderTransformOrigin="0.5,0.5" Command="{Binding ButtonClickCommand}">


или если у вас есть ссылка на вашу viewmodel в вашем xaml.cs, то на этом событии просто возьмите свою viewmodel и сделайте что-то вроде этого
FilterCriteria criteria = new FilterCriteria()
{ //populate properties here or however you populate your object
};

vm.FilterCriteriaList.Add(criteria); //This add triggers the INotify in ObservableCollection


Ваш ряд должен добавить.