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

从DataGrid更新WPF

  •  0
  • Chris  · 技术社区  · 15 年前

    我在WPF中有一个由csv文件填充的数据报。 这是通过linq完成的,并通过collectionviewsource.source填充数据报。

    要求对DataGrid中的数据进行任何更新/更改,然后将其保存回CSV。

    我需要知道如何保存对数据的任何更改?我一直在玩一些事件和数据上下文之类的东西,但还没有起作用。

    如果这是初学者的类型问题,我很抱歉。从Windows应用程序到WPF的转变是一个陡峭的学习曲线(至少对我来说)。 我刚从一个数组中填充了一段时间,现在我正在尝试解决这个问题。基本上只需要再次将数据取出,将其保存为var。

      System.Windows.Data.CollectionViewSource personViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("personViewSource")));
    
            List<Person> T = new List<Person>();
              Person p = new Person();
    
              string[] str = new string[] { "Stacey", "Olivia", "Dylan", "Lauryn", "Beth", "Caitlin" };
              var data = from s in str
                         select s;
              Person pers;
              foreach (var d in data)
              {
                  pers = new Person();
                  pers.Name = d;
                  pers.Age = 22;
                  T.Add(pers);
              }
    
    
            personViewSource.Source = T;
    

    XAML:

    <Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" Name="win1" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:my="clr-namespace:WpfApplication4">
    <Window.Resources>
        <CollectionViewSource x:Key="personViewSource" d:DesignSource="{d:DesignInstance my:Person, CreateList=True}" />
    </Window.Resources>
    <StackPanel Width="369" Height="230" DataContext="{StaticResource personViewSource}">
        <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" Name="personDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="88" HorizontalAlignment="Left" BorderThickness="4" Background="#FFF8C5C5" SelectionChanged="personDataGrid_SelectionChanged" TextInput="personDataGrid_TextInput" RowEditEnding="personDataGrid_RowEditEnding" TargetUpdated="personDataGrid_TargetUpdated">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="nameColumn" Binding="{Binding Path=Name, Mode=TwoWay, NotifyOnTargetUpdated=True}" Header="Name" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="ageColumn" Binding="{Binding Path=Age}" Header="Age" Width="SizeToHeader" Foreground="#FFC14040" />
            </DataGrid.Columns>
        </DataGrid>
    </StackPanel>
    

    谢谢

    1 回复  |  直到 15 年前
        1
  •  1
  •   Aran Mulholland JohnnyAce    15 年前

    您可以监听事件,了解单元格何时结束编辑,然后保存数据源。也就是说,在initializecomponent()调用之后,将其放入承载网格的控件(可能是用户控件、窗口、页面等)的构造函数中。

       this.myDataGrid.CellEditEnding += new EventHandler<DataGridCellEditEndingEventArgs>(grid_CellEditEnding);
    

    然后让处理程序保存数据源

      void grid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) {
         //save my data source
      }
    

    我个人更喜欢这样的方法,你可以执行你的编辑,然后点击保存在最后,但在你的情况下,你可以使用string.join创建一个csv字符串,然后写到一个文件。

    要执行此操作,请创建一个属性,该属性是您的列表,因此您为网格构建的数据如下所示:

    public Collection<Person> MyPersonDataSource {get; private set; }
    
    public MyWindowsConstructor() {
        //build the grid data before you initialize the window, as the PersonDataSource
        //does not implement NotifyPropertyChanged, if you build the data afterwards
        //the binding won't be updated
        BuildGridData();
        InitializeComponent();
    } 
    
    
    private void BuildGridData(){
    
      this.MyPersonDataSource = new Collection<Person>();
      Person p = new Person();
    
      string[] str = new string[] { "Stacey", "Olivia", "Dylan", "Lauryn", "Beth", "Caitlin" };
      var data = from s in str
                 select s;
      Person pers;
      foreach (var d in data)
      {
         pers = new Person();
         pers.Name = d;
         pers.Age = 22;
         this.MyPersonDataSource.Add(pers);
      }
    }
    

    然后在单元结束编辑功能中

      void grid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) {
         //save my data source
         var nameArray = this.MyPersonDataSource.Select(item => item.Name).ToArray();
         //create the csv string
         String csvString = String.Join("," nameArray);
         //write it to a file
         System.IO.File.WriteAllText(@"C:\SomeFolderYouHavePermissionsOn\names.csv", csvString);
      }
    

    我将把网格直接绑定到属性mypersonaldatasource,就像这样……

    <Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" Name="win1" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:my="clr-namespace:WpfApplication4">
    <Window.Resources>
        <CollectionViewSource x:Key="personViewSource" Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=MyPersonDataSource}" d:DesignSource="{d:DesignInstance my:Person, CreateList=True}" />
    </Window.Resources>
    <StackPanel Width="369" Height="230" DataContext="{StaticResource personViewSource}">
        <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" Name="personDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="88" HorizontalAlignment="Left" BorderThickness="4" Background="#FFF8C5C5" SelectionChanged="personDataGrid_SelectionChanged" TextInput="personDataGrid_TextInput" RowEditEnding="personDataGrid_RowEditEnding" TargetUpdated="personDataGrid_TargetUpdated">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="nameColumn" Binding="{Binding Path=Name, Mode=TwoWay, NotifyOnTargetUpdated=True}" Header="Name" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="ageColumn" Binding="{Binding Path=Age}" Header="Age" Width="SizeToHeader" Foreground="#FFC14040" />
            </DataGrid.Columns>
        </DataGrid>
    </StackPanel>
    </Window>
    

    我可能会看到比csv更强大的数据存储,您可以使用XML并使用xpath绑定到它,但我还没有足够的使用它来构建一个合适的答案。

    推荐文章