2010-07-17 81 views
0

我有一个从csv文件填充的WPF中的数据网格。 这是通过Linq完成的,并通过CollectionViewSource.Source填充数据网格。来自datagrid的WPF更新

要求是对数据网格中的数据进行更新/更改,然后将其保存回csv。

我需要知道如何保存对数据的任何更改?我一直在玩一些事件和datacontext和类似的东西,但没有任何工作。

我很抱歉,如果这是一个初学者的类型的问题。从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> 

感谢

+0

你想如何工作? datagrid应该将这些值自动保存到文件中吗?或者每当一个按钮被按下或者一样手动的时候?另外,也许向我们展示将数据放入DataGrid的代码会很有帮助。 – Goblin 2010-07-17 18:13:59

+0

自动或通过提交按钮。我只是在努力让自己的头转向它 – Chris 2010-07-17 19:20:18

+0

是您的数据正确显示?因为如果它正在编辑它应该更新您的人物对象,请在属性的其中一个setter上放置一个断点以确保。 – 2010-07-18 23:57:26

回答

1

你可以听当细胞结束编辑的事件,然后保存您的数据源。 (在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); 
    } 

我将我的网绑定直奔财产MyPersonDataSource,像这样..

<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绑定到它,但我没有足够使用它来构建适当的答案。

+0

如何保存数据源? – Chris 2010-07-19 06:13:12

+0

阿兰谢谢。你能解释一下如何将它直接绑定到myPersonDataSource? 如果我将所有的csv转换为xml还有更好的方法吗? – Chris 2010-07-19 13:06:08

+0

如果我没有错误DataGrid.CellEditEnding事件触发每一个被修改的单元格,对吗?比方说,用户通过网格并修改RowA的Cell1,Cell2和Cell3中的值。我正确预计DataGrid.CellEditEnding发射3次?如果是这样,对我来说似乎有点过分 - 每次编辑都要保存网格更改。但更重要的是,我如何实现行验证?因为在许多情况下,Cell1中的值可能会驱动Cell2的可用选项,等等=>您只能验证并保存整行,而不是逐个单元。 – Astrogator 2012-09-14 17:50:32