代码之家  ›  专栏  ›  技术社区  ›  devuxer

使用绑定控制数据报中的列顺序

  •  12
  • devuxer  · 技术社区  · 15 年前

    问题

    我有一个WPF工具包 DataGrid ,我想能够在几个预设的列顺序之间切换。这是一个MVVM项目,因此列顺序存储在 ViewModel . 问题是,我无法让绑定为 DisplayIndex 财产。不管我怎么尝试,包括 this Josh Smith tutorial 我得到:

    标题为“id”的DataGridColumn的DisplayIndex超出范围。DisplayIndex必须大于或等于0且小于Columns.Count。参数名称:DisplayIndex。实际值为-1。

    有什么解决办法吗?

    我在下面包含我的测试代码。如果你看到它有什么问题,请告诉我。


    视图模型代码

    public class MainViewModel
    {
        public List<Plan> Plans { get; set; }
        public int IdDisplayIndex { get; set; }
        public int NameDisplayIndex { get; set; }
        public int DescriptionDisplayIndex { get; set; }
    
        public MainViewModel()
        {
            Initialize();
        }
    
        private void Initialize()
        {
            IdDisplayIndex = 1;
            NameDisplayIndex = 2;
            DescriptionDisplayIndex = 0;
            Plans = new List<Plan>
            {
                new Plan { Id = 1, Name = "Primary", Description = "Likely to work." },
                new Plan { Id = 2, Name = "Plan B", Description = "Backup plan." },
                new Plan { Id = 3, Name = "Plan C", Description = "Last resort." }
            };
        }
    }
    

    计划类

    public class Plan
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
    

    窗口代码 -此用途 Josh Smith's DataContextSpy

    <Window
        x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:mwc="http://schemas.microsoft.com/wpf/2008/toolkit"
        Title="Main Window" Height="300" Width="300">
        <Grid>
            <mwc:DataGrid ItemsSource="{Binding Plans}" AutoGenerateColumns="False">
                <mwc:DataGrid.Resources>
                    <local:DataContextSpy x:Key="spy" />
                </mwc:DataGrid.Resources>
                <mwc:DataGrid.Columns>
                    <mwc:DataGridTextColumn
                        Header="ID" 
                        Binding="{Binding Id}"
                        DisplayIndex="{Binding Source={StaticResource spy}, Path=DataContext.IdDisplayIndex}" />
                    <mwc:DataGridTextColumn
                        Header="Name"
                        Binding="{Binding Name}"
                        DisplayIndex="{Binding Source={StaticResource spy}, Path=DataContext.NameDisplayIndex}" />
                    <mwc:DataGridTextColumn
                        Header="Description"
                        Binding="{Binding Description}"
                        DisplayIndex="{Binding Source={StaticResource spy}, Path=DataContext.DescriptionDisplayIndex}" />
                </mwc:DataGrid.Columns>
            </mwc:DataGrid>
        </Grid>
    </Window>
    

    注: 如果我只是用普通数字 显示索引 ,一切正常,所以问题肯定是绑定的问题。


    5/1/2010更新

    我只是对我的项目做了一点维护,当我运行它时,我在这篇文章中讨论的问题又回来了。我知道上次运行它时它是有效的,所以我最终把问题缩小到安装了较新版本的WPF工具包(2月10日)这一事实上。当我恢复到2009年6月的版本时,一切又恢复了正常。所以,我现在正在做我应该首先做的事情:我将wpftoolkit.dll包含在我的解决方案文件夹中,并将其签入版本控制。然而,不幸的是,新的工具箱有了一个突破性的变化。

    3 回复  |  直到 11 年前
        1
  •  4
  •   Aviad P.    15 年前

    (我以前的答案偏离了轨道-所以我删除了它-我将在我的机器上复制错误后再次尝试回答)

    您遇到的问题源于这样一个事实:当第一次评估绑定时, DataContext 属性仍设置为 null . 这是由于某种奇怪的原因,但我不知道,导致绑定在 -1 . 但是,如果您确定要设置 数据上下文 之前 对绑定进行评估,您会没事的。不幸的是,这可能只能在代码隐藏中实现——因此在运行时,而不是在设计时。所以在设计阶段,我仍然不知道如何规避这个错误。

    为此,请设置 数据上下文 调用前窗口的属性 InitializeComponent 因此:

    public MainWindow()
    {
        DataContext = new MainViewModel();
        InitializeComponent();
    }
    

    希望这有帮助。

        2
  •  12
  •   Pakman    14 年前

    集合 FallbackValue=<idx> 在DisplayIndex绑定中,其中 <idx> 是列的索引。例如:

    DisplayIndex="{Binding Source={StaticResource spy}, Path=DataContext.IdDisplayIndex, FallbackValue=0}" />
    
        3
  •  1
  •   Noxxys    11 年前

    我将添加此作为答案,因为我还不能发表评论。DisplayIndex值设置为-1的原因是:

    在添加DisplayIndex属性之前,它的默认值为-1。 到DataGrid.Columns集合。当 列被添加到数据报中。

    DataGrid要求每个列的DisplayIndex属性 必须是从0到列计数-1的唯一整数。因此, 当一列的DisplayIndex更改时,通常 使其他列的显示索引也发生更改。

    对DisplayIndex值的限制由 validateValueCallback机制。如果您试图设置的值是 无效,引发运行时异常。

    当DisplayIndex属性的值更改时, 引发了DataGrid.ColumnDisplayIndexChanged事件。

    资料来源: http://msdn.microsoft.com/en-us/library/vstudio/system.windows.controls.datagridcolumn.displayindex(v=vs.100).aspx

    因此,我认为当使用上述事件更改该值时,可以检查该值。

    Aviad提到的解决方案对我不起作用。我的DataGrid在一个用户控件中,与OP相同,并更改 ViewModel 建造师 DataContext 声明,以及 InitializeComponent() 方法没有帮助。

    Pakman FallbackValue 另一方面,这种方法很有效。

    推荐文章