对WPF数据网格列重新排序

对WPF数据网格列重新排序,wpf,datagrid,Wpf,Datagrid,我想给用户一个设置,在那里他可以对数据网格的列重新排序。我知道我可以使用DisplayIndex来实现这一点,但我的问题是如何保存每个列的顺序,如何知道哪些列移动到了第一个位置,等等 我考虑过使用列标题,但我不知道这是否是最好的解决方案 下面是im使用的数据网格: <DataGrid GridLinesVisibility="All" VerticalGridLinesBrush="#FFE5E2DB" IsReadOnly="true" AutoGenerateColumns="Fals

我想给用户一个设置,在那里他可以对
数据网格的列重新排序。我知道我可以使用
DisplayIndex
来实现这一点,但我的问题是如何保存每个列的顺序,如何知道哪些列移动到了第一个位置,等等

我考虑过使用列标题,但我不知道这是否是最好的解决方案

下面是im使用的数据网格:

<DataGrid GridLinesVisibility="All" VerticalGridLinesBrush="#FFE5E2DB" IsReadOnly="true" AutoGenerateColumns="False" VerticalContentAlignment="Center" 
                      ItemsSource="{Binding DisplayIndexes, UpdateSourceTrigger=PropertyChanged}" CanUserSortColumns="True" SelectionUnit="FullRow" 
                      HorizontalAlignment="Stretch" Margin="5,5,5,0" Name="dgDisplayIndexes"  
                      TabIndex="1" RowHeight="30" 
                      CanUserAddRows="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" ColumnWidth="Auto" CanUserReorderColumns="True" 
                      CanUserResizeColumns="False" CanUserResizeRows="False" VerticalAlignment="Top" Height="150">
                <DataGrid.RowStyle>
                    <Style TargetType="{x:Type DataGridRow}">
                        <Setter Property="Padding" Value="0"/>
                        <Setter Property="Margin" Value="0"/>
                        <Setter Property="VerticalAlignment" Value="Center"/>
                    </Style>
                </DataGrid.RowStyle>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" Binding="{Binding ID}" DisplayIndex="0" Visibility="Hidden" />
                    <DataGridTemplateColumn SortMemberPath="status"  
                                        Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_STATUS.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                                        DisplayIndex="1" >
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Image Height="16" Width="16" Stretch="Fill" Source="{Binding status, Converter={StaticResource getIconForStatus}}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn 
                    Header="#" 
                    Binding="{Binding bonnummer}"  
                    DisplayIndex="2" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_NAAM.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding achternaam}" 
                    DisplayIndex="3" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_ADRES.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding Adres}" 
                    DisplayIndex="4" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_PC.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding Postcode}" 
                    DisplayIndex="5" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_PLAATS.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding plaats}" 
                    DisplayIndex="6"/>
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_TELEFOON.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding telefoonnummer}" 
                    DisplayIndex="7" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_AANTALBESTELLINGEN.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding AantalBestellingen}" 
                    DisplayIndex="8" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_KAARTCOORDINATEN.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding Coordinaten}" 
                    DisplayIndex="9" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_GEBIED.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding bezorggebied}" 
                    DisplayIndex="10" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_KM.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding afstand, StringFormat='{}{0:N2}'}" 
                    DisplayIndex="11" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_REISTIJD.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding reistijd}" 
                    DisplayIndex="12" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_TIJD.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding tijd, StringFormat={}{0:HH:mm}}" 
                    DisplayIndex="13" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_OUD.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding oud}" 
                    DisplayIndex="14" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_BEZORGTIJD.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding gereed_om, StringFormat={}{0:HH:mm}}" 
                    DisplayIndex="15" />
                    <DataGridTextColumn     
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_BEZORGER.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding bezorger}" 
                    DisplayIndex="16" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_VERTROKKEN.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding bezorger_vertrokken_om, StringFormat={}{0:HH:mm}}" 
                    DisplayIndex="17" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_OVER.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding bezorgerterugover}" 
                    DisplayIndex="18" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_TERUG.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding bezorgerterug, StringFormat={}{0:HH:mm}}" 
                    DisplayIndex="19" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_KEUKEN.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding keuken}" 
                    DisplayIndex="20" />
                    <DataGridTextColumn 
                    Header="{Binding Vertaling.DELIVERY_BEZORGORDER_LOPENDEORDERSTAB_DG_TELAATBERICHTUITOM.Vertaling, Source={x:Static Application.Current}, NotifyOnSourceUpdated=True}" 
                    Binding="{Binding TeLaatBerichtTijd, StringFormat={}{0:HH:mm}}" 
                    DisplayIndex="21" />
                </DataGrid.Columns>
            </DataGrid>

您可以将DataGrid的DisplayIndex属性绑定到ViewModel中的属性:

...
<DataGridTextColumn 
                    Header="#" 
                    Binding="{Binding bonnummer}"  
                    DisplayIndex="{Binding BonnummerIndex, Mode=TwoWay, FallbackValue=2}" ... />
...
。。。
...
BonnummerIndex是存储列显示位置的ViewModel属性。您还可以绑定到数组元素ie.
DisplayIndex=“{Binding ColumnsOrder[2],Mode=TwoWay,FallbackValue=2}”
。FallbackValue设置为默认列位置。您需要这样做,以避免DisplayIndex的默认值(-1),这反过来会抛出超出范围的异常。需要双向bindig将用户更改反映回ViewModel中

稍后,您可以序列化/反序列化类以保存用户设置


您只需小心,因为更改一列的DisplayIndex可能会更改其他列的DisplayIndex。

您可以将DataGrid的DisplayIndex属性绑定到ViewModel中的属性:

...
<DataGridTextColumn 
                    Header="#" 
                    Binding="{Binding bonnummer}"  
                    DisplayIndex="{Binding BonnummerIndex, Mode=TwoWay, FallbackValue=2}" ... />
...
。。。
...
BonnummerIndex是存储列显示位置的ViewModel属性。您还可以绑定到数组元素ie.
DisplayIndex=“{Binding ColumnsOrder[2],Mode=TwoWay,FallbackValue=2}”
。FallbackValue设置为默认列位置。您需要这样做,以避免DisplayIndex的默认值(-1),这反过来会抛出超出范围的异常。需要双向bindig将用户更改反映回ViewModel中

稍后,您可以序列化/反序列化类以保存用户设置


您只需要小心,因为更改一列的DisplayIndex可能会更改另一列的DisplayIndex。

谢谢您的回复,但我已经知道如何做,将DisplayIndex绑定到我的viewmodel上的属性,并设置回退值以防止异常。我的问题更多的是在设置方面,我允许用户更改列的位置,这样当他用数据网格加载用户控件时,列将保留在他设置它们的位置上。例如,我的疑问是如何跟踪位置0上的列和位置2上的列。我希望您现在能理解我的问题。如果您将DisplayIndex绑定到ViewModel上的属性,那么当用户重新排序列(拖放列)时,绑定将自动更新ViewMonel。要持久化数据,您可以将存储DisplayIndexes的对象序列化到磁盘,并在应用程序/控件加载时从磁盘反序列化。谢谢,我能够通过创建一个新类并保存每列的索引来解决此问题,我稍后将调用包含datagrid的usercontrol。谢谢您的回复,但我已经知道该怎么做了,将displayIndex绑定到viewmodel上的属性,并设置回退值以防止异常。我的问题更多的是在设置方面,我允许用户更改列的位置,这样当他用数据网格加载用户控件时,列将保留在他设置它们的位置上。例如,我的疑问是如何跟踪位置0上的列和位置2上的列。我希望您现在能理解我的问题。如果您将DisplayIndex绑定到ViewModel上的属性,那么当用户重新排序列(拖放列)时,绑定将自动更新ViewMonel。要持久化数据,您可以将存储DisplayIndexes的对象序列化到磁盘,并在应用程序/控件加载时从磁盘反序列化。谢谢,我能够通过创建一个新类并保存每列的索引来解决此问题,我稍后将调用包含datagrid的usercontrol。