Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从datagrid更新WPF_C#_Wpf_Datagrid - Fatal编程技术网

C# 从datagrid更新WPF

C# 从datagrid更新WPF,c#,wpf,datagrid,C#,Wpf,Datagrid,我有一个从csv文件填充的WPF中的datagrid。 这是通过Linq完成的,并通过CollectionViewSource.Source填充datagrid 要求对datagrid中的数据进行任何更新/更改,然后将其保存回csv 我需要知道如何保存对数据的任何更改?我一直在玩一些事件和datacontext之类的东西,但还没有任何效果 如果这是初学者类型的问题,我很抱歉。从windows应用程序到WPF是一个陡峭的学习曲线(至少对我来说)。 我现在只是从一个数组中填充,而我正在尝试解决它。基

我有一个从csv文件填充的WPF中的datagrid。 这是通过Linq完成的,并通过CollectionViewSource.Source填充datagrid

要求对datagrid中的数据进行任何更新/更改,然后将其保存回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;
System.Windows.Data.CollectionViewSource personViewSource=((System.Windows.Data.CollectionViewSource)(this.FindResource(“personViewSource”));
列表T=新列表();
人员p=新人员();
字符串[]str=新字符串[]{“Stacey”、“Olivia”、“Dylan”、“Lauryn”、“Beth”、“Caitlin”};
变量数据=来自str中的s
选择s;
个人资料;
foreach(数据中的var d)
{
pers=新人();
pers.Name=d;
人均年龄=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>


谢谢

您可以在单元格结束编辑时收听事件,然后保存数据源。i、 e.在InitializeComponent()调用之后,将其放入承载网格的控件(可能是用户控件、窗口、页面等)的构造函数中

就个人而言,我更喜欢这样一种方法,即您可以执行编辑,然后在最后单击“保存”,但在您的情况下,您可以使用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);
  }
}
我会直接将我的网格绑定到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绑定到它,但我还没有充分使用它来构建适当的答案。

您希望它如何工作?datagrid是否应该自动将值保存到文件中?或者每当按下一个按钮或其他类似的手动操作时?另外,也许首先向我们展示将数据放入DataGrid的代码会很有帮助。可以是自动的,也可以是通过submit按钮。我只是想弄清楚你的数据显示正确吗?因为如果它正在编辑,它应该更新您的person对象,请在属性的一个设置器上设置断点以确保。Aran数据按照上面的代码正确显示。不用担心,chris,对我的回答进行了编辑如何保存数据源?Aran谢谢。您能解释一下如何将它直接绑定到myPersonDataSource吗?如果我将所有csv转换为xml,还有更好的方法吗?如果我没有弄错的话,DataGrid.CellEditEnding事件会为每个被修改的单元格激发,对吗?假设用户遍历网格并修改RowA的Cell1、Cell2和Cell3中的值。我期望DataGrid.CellEditEnding触发3次,对吗?如果是这样,对我来说似乎有点过分——每次编辑时保存网格更改。但更重要的是,如何实现行验证?因为在许多情况下,Cell1中的值可能会驱动Cell2的可用选项,以此类推=>您只能验证和保存整行,而不能逐个单元格。
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);
  }
<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>