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 шт):
Я думаю что, это нужно делать в разметке 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.
для моего случая задача решается следующим способом (От общего случая может отличаться тем. что 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>