WPF DataGrid Navision功能

时间:2011-07-19 12:54:50

标签: c# wpf datagrid navision

我正在创建一个 DataGrid ,其功能与 Microsoft Dynamic Nav 相同。
这几乎就像一个Excel电子表格。

这个想法是你可以开始编辑一个单元格。完成后,有一些步骤:

  1. 根据列表验证单元格的内容 1.1如果列表包含给定的字符串(不区分大小写),则DataGrid中的内容将替换为列表中的字符串(也就是案例​​正确的字符串)。
    1.2如果列表不包含字符串,它将显示一个可能的新表单,然后使用用户选择的表单替换已经键入DataGrid的表单。

  2. 如果用户输入了正确的内容或从列表中选择了正确的值,则DataGrid会自动使用预设字符串填充某些列

  3. 如果我们看一个例子:如果用户在第1列中键入z,那么我希望第2列变为“x”并将焦点移至colum3

    DataGrid: (Before enter/Tab pressed)
    
    [Column1] [Column2] [Column3] [Column4]
    [  "a"  ] [  "b"  ] [  "c"  ] [  "d"  ]
    [  "z"  ] [       ] [       ] [       ]
    (focused)
    
    DataGrid: (Afture enter/tab pressed
    [Column1] [Column2] [Column3] [Column4]
    [  "a"  ] [  "b"  ] [  "c"  ] [  "d"  ]
    [  "z"  ] [  "x"  ] [       ] [       ]
                        (focused)
    

    在这里我遇到了一些问题:

    1. 我使用CellEditEnding事件来验证文本输入。如果我找到了正确的文本,那么我会在正确的变量上编辑currentItem。但现在我需要调用dataGrid1.Items.Refresh();而不是在编辑模式下完成。
    2. mycode的:

      FormTest.xaml

      ...
      <DataGrid.Columns>
          <DataGridTextColumn Header="C1" 
              Binding="{Binding c1,UpdateSourceTrigger=LostFocus}"/>
          <DataGridTextColumn Header="C2" 
              Binding="{Binding c2,UpdateSourceTrigger=LostFocus}"/>
          <DataGridTextColumn Header="C3" 
              Binding="{Binding c3,UpdateSourceTrigger=LostFocus}"/>
          <DataGridTextColumn Header="C4" 
              Binding="{Binding c4,UpdateSourceTrigger=LostFocus}"/>
          <DataGridTextColumn Header="C5" 
              Binding="{Binding c5,UpdateSourceTrigger=LostFocus}"/>
      </DataGrid.Columns>
      ...
      

      FormTest.xaml.cs

      public FormTest()
      {
          InitializeComponent();
          loadMockData();
      }
      private void loadMockData()
      {
          dataItems = new DataItems();
          dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
          dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
          dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
          dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
          dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
      
          dataGrid1.ItemsSource = dataItems;
      }
      private void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
      {
          TextBox editElement = e.EditingElement as TextBox;
          DataItem di = dataGrid1.CurrentItem as DataItem;
          DataGridCellInfo cell = dataGrid1.CurrentCell;
          if (e.Column.DisplayIndex == 0)
          {
              if (editElement.Text == "z")
              {
                  editElement.Text = "Z"; 
                  di.c1 = "Z";
                  di.c2 = "X";
              }
          }
      }
      private void dataGrid1_PreviewKeyDown(object sender, KeyEventArgs e)
      {
          if (e.Key == Key.Enter || e.Key == Key.Tab)
          {
              dataGrid1.CommitEdit();
              DataItem di = dataGrid1.CurrentItem as DataItem;
              dataGrid1.CancelEdit();
              dataGrid1.Items.Refresh();
           }
      }
      
      private class DataItems : List<DataItem> { }
      private class DataItem
      {
          public int recID { get; set; }
          public String c1 { get; set; }
          public String c2 { get; set; }
          public String c3 { get; set; }
          public String c4 { get; set; }
          public String c5 { get; set; }
      }
      

      我在这段代码中遇到的问题是:

      1. 调用刷新后,没有选定的单元格。这意味着如果不使用鼠标选择单元格,就无法继续输入数据。

      2. 当我开始输入新项目(又名空行),然后按Enter或Tab键时,dataGrid1.CancelEnding()将删除新项目,并且该行再次为空。

        < / LI>

        问题

        • 是否可以在不调用ItemSoure的情况下编辑数据网格的内容(Items.Refresh()以及显示的内容)?
        • 如果不是,可以在Items.Refresh()完成后设置单元格焦点。 ?
        • 或者有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我可以回答有关更新网格内容的问题。

通常,在更改一个属性后不必刷新整个网格。 (如果您的网格中有大量数据,那也相当浪费。)如果您的班级DataItem实现了INotifyPropertyChanged界面,并且您每次都会触发PropertyChanged个事件其中一个属性更改后,WPF将自动更新表中的数据。

This page on MSDN包含实现此接口的示例,您可以找到使用此接口here的更完整示例。

这应该摆脱使用dataGrid1_PreviewKeyDown事件处理程序的需要,而后者反过来解决了无法在网格底部添加新行的问题。

您还应该将Mode=TwoWay添加到Binding中的DataGridTextColumn。否则,当您编辑单元格时,WPF将不会使用您在网格中输入的值更新相关的DataItem对象。

在第一列中输入一个值之后,我看了第二列的“tab”方法,但是我没有找到任何有效的方法。