2010-07-17 82 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