Обновление данных, привязанных к элементу управления DataGrid (тема MaterialDesign), с прикрепленными поведениями с использованием WPF MVVM?

У меня интерфейсный код DataGrid выглядит так:

<DataGrid  ItemsSource="{Binding DTDisplayData}" x:Name="dgReport"
                   attached:DataGridColumnsAttched.BindableColumns="{Binding ColumnCollection}"
                   AutoGenerateColumns="False" CanUserDeleteRows="False" IsReadOnly="False"
                   CanUserSortColumns="True" CanUserAddRows="False" Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="3" BorderBrush="#89000000" BorderThickness="1"
                   >

            <DataGrid.Style>
                <Style TargetType="DataGrid" BasedOn="{StaticResource MaterialDesignDataGrid}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding SelectedBox}" Value="{x:Null}">
                            <Setter Property="Visibility" Value="Collapsed"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Style>

        </DataGrid>

С классом, прикрепленным к серверному коду .CS:

public class DataGridColumnsAttched
{
public static readonly DependencyProperty BindableColumnsProperty =
        DependencyProperty.RegisterAttached("BindableColumns",
                                            typeof(ObservableCollection<DataGridColumnMetaData>),
                                            typeof(DataGridColumnsAttched),
                                            new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
        private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            DataGrid dataGrid = source as DataGrid;
            ObservableCollection<DataGridColumnMetaData> columns = e.NewValue as ObservableCollection<DataGridColumnMetaData>;
            dataGrid.Columns.Clear();
            if (columns == null)
            {
                return;
            }

            foreach (DataGridColumnMetaData column in columns)
            {
                dataGrid.Columns.Add(CreateColumnFromMetaData(column));
            }

            columns.CollectionChanged += (sender, e2) =>
            {
                NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
                if (ne.Action == NotifyCollectionChangedAction.Reset)
                {
                    dataGrid.Columns.Clear();
                    if(ne.NewItems != null)
                    { 
                        foreach (DataGridColumnMetaData column in ne.NewItems)
                        {
                            dataGrid.Columns.Add(CreateColumnFromMetaData(column));
                        }
                    }
                }
                else if (ne.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (DataGridColumnMetaData column in ne.NewItems)
                    {
                        dataGrid.Columns.Add(CreateColumnFromMetaData(column));
                    }
                }
                else if (ne.Action == NotifyCollectionChangedAction.Move)
                {
                    dataGrid.Columns.Move(ne.OldStartingIndex, ne.NewStartingIndex);
                }
                else if (ne.Action == NotifyCollectionChangedAction.Remove)
                {
                    foreach (DataGridColumnMetaData column in ne.OldItems)
                    {
                        dataGrid.Columns.Remove(CreateColumnFromMetaData(column));
                    }
                }
                else if (ne.Action == NotifyCollectionChangedAction.Replace)
                {
                    dataGrid.Columns[ne.NewStartingIndex] = ne.NewItems[0] as DataGridColumn;
                }
            };
        }
        public static void SetBindableColumns(DependencyObject element, ObservableCollection<DataGridColumn> value)
        {
            element.SetValue(BindableColumnsProperty, value);
        }
        public static ObservableCollection<DataGridColumn> GetBindableColumns(DependencyObject element)
        {
            return (ObservableCollection<DataGridColumn>)element.GetValue(BindableColumnsProperty);
        }

        public static DataGridColumn CreateColumnFromMetaData(DataGridColumnMetaData columnMetaData)
        {
            DataGridColumn newColumn;
            switch (columnMetaData.Type)
            {
                case SuperTapiModel.ColumnType.DataGridTextColumn:
                    {
                        DataGridTextColumn dgcText = new DataGridTextColumn();
                       //set parameters....
                        newColumn = dgcText;
                    }
                    break;
                case SuperTapiModel.ColumnType.DataGridTemplateColumn:
                    { 
                        DataGridTemplateColumn dgcTemplate = new DataGridTemplateColumn();
                        newColumn = dgcTemplate;
                    }
                    break;
                case SuperTapiModel.ColumnType.DataGridHyperlinkColumn:
                    {
                        DataGridHyperlinkColumn dgcHyperlink = new DataGridHyperlinkColumn();
                        newColumn = dgcHyperlink;
                    }
                    break;
                case SuperTapiModel.ColumnType.DataGridComboBoxColumn:
                    {
                        DataGridComboBoxColumn dgcComboBox = new DataGridComboBoxColumn();
                        newColumn = dgcComboBox;
                    }
                    break;
                case SuperTapiModel.ColumnType.DataGridCheckBoxColumn:
                    {
                        DataGridCheckBoxColumn dgcCheckBox = new DataGridCheckBoxColumn();
                        newColumn = dgcCheckBox;
                    }
                    break;
                default:
                    {
                        DataGridTextColumn dgcText = new DataGridTextColumn();
                       //set parameters....
                        newColumn = dgcText;
                    }
                    break;
            }
            return newColumn;
        }
}

Я хочу редактировать данные в сетке данных, и я предполагаю, что мне нужно поймать событие редактирования PropertyChanged при редактировании ячейки.

Затем я хочу установить параметр EditingElementStyle во внутреннем коде .CS.

Как я могу добиться этого с помощью WPF и MVVM?

Стоит отметить, что исходный код моего кода основан на теме MaterialDesign, в которой, как мне кажется, не хватает некоторых ресурсов, с которыми я мог бы поиграть.

Любая помощь могла бы быть полезна!


person Bati    schedule 14.11.2019    source источник


Ответы (1)


Для первой части вашей проблемы, части редактирования, вам нужно будет привязать свойство «Привязка» ваших столбцов к связанному свойству ViewModel, которое вы хотите изменить, когда пользователь редактирует ячейку. Поскольку вы создаете свои столбцы из файла .cs, вы должны сделать это так:

case SuperTapiModel.ColumnType.DataGridTextColumn:
{
    DataGridTextColumn dgcText = new DataGridTextColumn();
    dgcText.Binding = new Binding("The name of the property");
    newColumn = dgcText;
}
break;

Обратите внимание, что я никогда не делал этого раньше, поэтому синтаксис может немного отличаться, но вы поняли идею.

Для второй части, поэтому, установив EditingElementStyle, вы должны сделать то же самое, что и Binding. Создайте свой стиль в файле Xaml, затем используйте метод FindResource, чтобы установить значение EditingElementStyle в файле .cs. Это будет выглядеть примерно так:

case SuperTapiModel.ColumnType.DataGridTextColumn:
{
    DataGridTextColumn dgcText = new DataGridTextColumn();
    dgcText.EditingElementStyle = FindResource("YourResourceKey") as Style;
    newColumn = dgcText;
}
break;

Надеюсь, это поможет!

person mgarant    schedule 18.11.2019
comment
Спасибо за ваш ответ, все еще нужна помощь, я использую MaterialDesignTheme для стиля, и FindResource не распознает их. Есть ли способ сделать это? - person Bati; 20.11.2019