C# WPF MVVM Сохранение последовательности столбцов DataGrid

Подскажите пожалуйста как реализовать сохранение последовательности столбцов в datagrid при использовании паттерна MVVM?

Ранее в приложении не использовал этот паттерн и решал вопрос так:

 [DataContract]
public class dataGridSettings
{
    [DataMember]
    public int columnNum { set; get; }
    [DataMember]
    public int displayIndex { set; get; }
    [DataMember]
    public int dataGridLength { set; get; }
    [DataMember]
    public int sorting { set; get; }
    [DataMember]
    public bool isHide { set; get; }
}

 private void dataGridViewSave()
    {
        savedSettings.gridSettingsList = new List<dataGridSettings>();

        for (int i = 0; i < dataGridView1.Columns.Count; i++)
        {
            dataGridSettings dataGridSettings = new dataGridSettings();

            dataGridSettings.columnNum = i;
            dataGridSettings.displayIndex = dataGridView1.Columns[i].DisplayIndex;
            if (dataGridView1.Columns[i].Width != DataGridLength.Auto)
            {
                dataGridSettings.dataGridLength = (int)(dataGridView1.Columns[i].ActualWidth);
            }

            switch (dataGridView1.Columns[i].SortDirection)
            {
                case null:
                    dataGridSettings.sorting = 0;
                    break;
                case System.ComponentModel.ListSortDirection.Ascending:
                    dataGridSettings.sorting = 1;
                    break;
                case System.ComponentModel.ListSortDirection.Descending:
                    dataGridSettings.sorting = 2;
                    break;
            }

            dataGridSettings.isHide = dataGridView1.Columns[i].Visibility == Visibility.Hidden;

            savedSettings.gridSettingsList.Add(dataGridSettings);

        }
    }

При таком варианте сохранялась не только последовательность сортировки, но и ширина столбцов заданная пользователем. теперь переписал проект под MVVM и в этом месте застопорился. С одной стороны вид табличного представления - это view. C другой стороны в code behind вроде как писать не желательно. Как решить эту задачу?


Ответы (2 шт):

Автор решения: Aleksandr Kurilov

Я думаю что, это нужно делать в разметке xaml. Вот пример разметки:

<DataGrid ItemsSource="{Binding Path=Items}"
                      SelectedItem="{Binding Path=SelectedItem}" 
                      AutoGenerateColumns="False"
                      SelectionMode="Single"
                      IsReadOnly="True"
                      IsEnabled="True">

    <DataGrid.Columns>

        <DataGridTextColumn Header="ColumnHeaderItem1" Width="Auto" MinWidth="100"
            Binding="{Binding Path=ItemProperty1}"
            IsReadOnly="True" CanUserResize="False" CanUserReorder="False"/>

        <DataGridTextColumn Header="ColumnHederItem2" Width="200" MaxWidth="200" MinWidth="200"
            Binding="{Binding Path=ItemProperty2, Converter={converters:ExempleConverter}}"
            IsReadOnly="True" CanUserResize="False" CanUserReorder="False"/>

        <DataGridTextColumn Header="ColumnHederItem3" Width="200" MaxWidth="200" MinWidth="200"
            Binding="{Binding Path=ItemProperty3}"
            IsReadOnly="False" CanUserResize="True" CanUserReorder="True"/>

    </DataGrid.Columns>
</DataGrid>

Такое решение можно использовать как для моделей которые заранее известны, так и для autogenerated. Всеми свойствами и атрибутами DataGrid можно управлять привязав их к свойствам в модели представления.

P.S. Если мой ответ не помог Вам, опишите Вашу проблему подробней и приложите разметку XAML в которой находится контрол DataGrid.

→ Ссылка
Автор решения: Deim

для моего случая задача решается следующим способом (От общего случая может отличаться тем. что ItemSource у меня привязан к iCollectionView):

        <DataGrid x:Name="MainCollectionDG" ItemsSource="{Binding DatagridICollectionView}" SelectedItem="{Binding CurrentSelectedFile, Mode=TwoWay}" 
              AutoGenerateColumns="False" SelectionChanged="SelectionChanged" IsSynchronizedWithCurrentItem="True" IsReadOnly="True" Margin="3">            
        <DataGrid.Resources> 

       <DataGridTextColumn Header="Date and Time" Binding="{Binding FileDateTime}" 
            Visibility="{Binding Data.DateAndTimeVisibility, Source={StaticResource ProxyElement}, 
            Converter={StaticResource VisibilityConv}}" 
            DisplayIndex="{Binding Data.DateAndTimeColumnPosition, Source={StaticResource ProxyElement}, Mode=TwoWay, FallbackValue=0}"/>

Fallback - позиция столбца по умолчанию. Для того чтобы прокинуть DataContext до столбца нужно использовать класс proxy:

class BindingProxy : Freezable
{
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy));
}

Далее объявить его:

    <Window.Resources>             
        <proxy:BindingProxy x:Key="ProxyElement" Data="{Binding}"/>
    </Window.Resources>
→ Ссылка