为xaml中的第一列启用DataGrid排序

时间:2016-10-19 05:36:08

标签: c# wpf sorting mvvm datagrid

我在WPF中有一个带有自动生成列的DataGrid。

如何禁用除我的Source中对应时间的第一行之外的所有行的排序功能。

我遵循MVVM模式,我知道CanUserSortColumns禁用所有列的排序。我想禁用除第一列之外的所有列。

我应该写触发器或交互还是别的什么?所有的帮助表示赞赏。

<DataGrid AutoGenerateColumns="True" 
        ItemsSource="{Binding MyDataTable}" 
        CanUserSortColumns="False">
</DataGrid>

2 个答案:

答案 0 :(得分:2)

我找到了这段代码snippet

<my:DataGridTemplateColumn  SortMemberPath="CompleteDate" Header="Complete Date" CanUserSort="true">
            <my:DataGridTemplateColumn.CellTemplate >
                    <DataTemplate>
                        <TextBlock>
                            <TextBlock.Text>
                                <Binding Path="CompleteDate" ConverterCulture="en-GB" StringFormat="{}{0:MM/dd/yyyy}"/>
                            </TextBlock.Text>
                        </TextBlock>
                    </DataTemplate>
                </my:DataGridTemplateColumn.CellTemplate>
            </my:DataGridTemplateColumn>

使用CanUserSort属性显式定义它的可排序状态列。 SortMemberPath定义用于排序的属性。希望这会有所帮助。

<强>更新 如果您使用的是自动生成的列,则无法通过xaml访问它们。所以你需要在代码文件中访问它们。

我不熟悉xaml网格,但希望有类似的东西:

//Bound Data here so that the Grid generate the columns

int i = 0;
foreach (DataColumn column in myGrid.ColumnCollection)
{
   if (i == 0)
      column.CanSortUser = true;
   else
      column.CanSortUser = false;

   i++;
}

原始的类型名称可能有所不同,但这种方式应该是可行的。

<强> UPDATE-2

如果您不想伤害MVVM,可以使用this。介绍了如何使用Interfaces访问代码并与视图和视图模型保持独立。

答案 1 :(得分:2)

问题是,DataGridColumnHeader具有CanUserSort属性作为本地计算属性。可以通过手动生成列(您不想要的)来设置它。

如果它是带有setter的属性,您可以创建DataTrigger查看TabIndex == 0并在xaml Style中设置Setter

使用AutoGeneratedColumns的唯一机会如下:

<DataGrid AutoGenerateColumns="True" 
    ItemsSource="{Binding MyDataTable}" 
    CanUserSortColumns="True"
    AutoGeneratedColumns="DataGrid_OnAutoGeneratedColumns">
</DataGrid>

你的代码隐藏:

private void DataGrid_OnAutoGeneratedColumns(object sender, EventArgs e)
{
    DataGrid dg = sender as DataGrid;
    if (dg == null) return;
    dg.Columns.ToList().Select((col, indx) => new {Col = col, Indx = indx}).ToList().ForEach(obj => obj.Col.CanUserSort = obj.Indx == 0);
}

这将启用第一列UserCanSort属性并禁用其他列。此功能独立于 viewmodel ,可以放在您的view.xaml.cs代码后面。

修改

如果您没有任何代码隐藏,您可以使用自己的DataGridControl来执行此操作。

MyDataGrid.cs

namespace YourNamespace {
    public class MyDataGrid : DataGrid
    {
        protected override void OnAutoGeneratedColumns(EventArgs e)
        {
            DataGrid dg = sender as DataGrid;
            if (dg == null) return;
            dg.Columns.ToList().Select((col, indx) => new {Col = col, Indx = indx}).ToList().ForEach(obj => obj.Col.CanUserSort = obj.Indx == 0);

            base.OnAutoGeneratedColumns(e);
        }
    }
}

你的观点:

<YourNamespace:MyDataGrid AutoGenerateColumns="True" 
    ItemsSource="{Binding MyDataTable}" 
    CanUserSortColumns="True">
</YourNamespace:MyDataGrid>

并且您完成了没有单行代码隐藏。