wpf 如何在 XAML 和 C# 中将字符串列表显示为 DataGrid(表)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28991304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:00:08  来源:igfitidea点击:

How to display a List of Strings as a DataGrid (table) in XAML and C#

c#wpfxamldatagriddatatable

提问by matrixanomaly

I've been a long time lurker on SO and have only recently decided to set up an account. I've been spending quite a lot of hours trying to solve this problem I've been having without asking but I here it is.

我在 SO 上潜伏了很长时间,直到最近才决定开设一个帐户。我花了很多时间试图解决这个我一直没有问的问题,但我在这里。

What I'm trying to accomplish:

我想要完成的事情:

I have a list of strings, e.g: Mango, Banana, Melon (let's call it fruits) and I want to display it as a table in XAML (WPF), where it appears as row values on the left side, and the right side will be combo boxes that will allow users to pick a value. I'm currently stuck on the displaying part of this problem. I decided to use a DataGrid to display the list, and the code behind will do the data bindings.

我有一个字符串列表,例如:Mango、Banana、Melon(我们称之为水果),我想将它显示为 XAML (WPF) 中的表格,在左侧和右侧显示为行值将是允许用户选择值的组合框。我目前被困在这个问题的显示部分。我决定使用 DataGrid 来显示列表,后面的代码将进行数据绑定。

Here's the XAML part of it:

这是它的 XAML 部分:

<DataGrid x:Name="FruitDataGrid" Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6" HorizontalAlignment="Left" Width="1188" AutoGenerateColumns="False"> 
 <!-- If AutoGenerateColumns was true only the length is displayed.-->
         <DataGrid.Columns>
         <DataGridTextColumn x:Name="fruitsDisplay" Header="Fruits" MinWidth="450" IsReadOnly="True" />
         <DataGridComboBoxColumn Header="Number of Boxes" MinWidth ="200" CanUserResize="True" Width="*"></DataGridComboBoxColumn>
  </DataGrid.Columns>

Code Behind so far has been really simple, and after many attempts this is the most recent one.

到目前为止,代码隐藏非常简单,经过多次尝试,这是最新的。

private void populateFruitList()
    {
        FruitDataGrid.DataContext = fruitDataTable;
        //Binds a datatable instance to the datagrid, does not display anything.
    }

What I've been attempting:

我一直在尝试:

Turn the List of Strings into an Observable Collection, or Enumerable, and do FruitDataGrid.itemsource = fruitsObservable;

把字符串列表变成一个 Observable 集合,或者 Enumerable,然后做 FruitDataGrid.itemsource =fruitObservable;

The above method works, except that it will only display the length of each string value (if autogeneratecolumns is true), which is not what I want. If autogeneratecolumns was false then I can see the rows being shown, but not the string values.

上面的方法有效,只是它只会显示每个字符串值的长度(如果 autogeneratecolumns 为真),这不是我想要的。如果 autogeneratecolumns 为 false,那么我可以看到显示的行,但看不到字符串值。

I also tried using DataView or DataGridView but I failed to define it in the XAML, VS2012 says that there isn't such a thing.

我也尝试过使用 DataView 或 DataGridView 但我没有在 XAML 中定义它,VS2012 说没有这样的东西。

I've been trying to do data binding as well as the MSDN Articlesays, but VS2012 never manages to bind to the list properly.

我一直在尝试进行数据绑定以及MSDN 文章所说的那样,但是 VS2012 从未设法正确绑定到列表。

I then attempted to change my list into a datatable and [use a datagridview as specified here but again the XAML tells me it is not a valid class][2]. I am also aware of the performance impact datagridview might have but at this point I just want to display a table really.

然后我尝试将我的列表更改为数据表并[使用此处指定的数据网格视图,但 XAML 再次告诉我它不是有效类][2]。我也知道 datagridview 可能对性能产生影响,但此时我只想真正显示一个表格。

I've also seen that some tutorials use a DataGrid.datasource method but that isn't in the DataGrid I want, I think it's a different class? (the DataGrid I am attempting to use is System.Windows.Controls.DataGrid, and the other one is in Windows Forms [As shown here][3])

我还看到一些教程使用 DataGrid.datasource 方法,但这不在我想要的 DataGrid 中,我认为它是一个不同的类?(我尝试使用的 DataGrid 是 System.Windows.Controls.DataGrid,另一个是在 Windows 窗体中 [如此处所示][3])

Thanks again for taking the time to look into this.

再次感谢您抽出时间来研究这个问题。

EDIT

编辑

Trying to bind to the list in XAML this way:

尝试以这种方式绑定到 XAML 中的列表:

<DataGrid x:Name="FruitDataGrid" Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6" HorizontalAlignment="Left" Width="1188" AutoGenerateColumns="False" ItemsSource="fruitDataList"> 

I get the error in XAML "The type converter for IEnumerable does not support converting from a string" which I think is because I'm doing it wrong. The table now shows a lot of empty rows though.

我在 XAML 中收到错误“IEnumerable 的类型转换器不支持从字符串转换”,我认为这是因为我做错了。不过,该表现在显示了很多空行。

Trying ItemSource="{Binding fruitDataList}" (where fruitDataList is a List) yields a blank table, and an error in VS for BindingExpression path error.

尝试 ItemSource="{BindingfruitDataList}"(其中fruitDataList 是一个列表)会产生一个空白表,并且在 VS 中会出现 BindingExpression 路径错误。

采纳答案by Muds

Considering your binding is set to your viewmodel correctly.. do this

考虑到您的绑定已正确设置为您的视图模型.. 这样做

ItemsSource="{Binding fruitDataList}"

then

然后

<DataGrid.Columns>
         <DataGridTextColumn 
x:Name="fruitsDisplay"
Binding="{Binding Path=FRUITS_PROPERTY_NAME_IN_COLLECTION}"
Header="Fruits"
MinWidth="450" 
IsReadOnly="True" />

         <DataGridComboBoxColumn
ItemsSource="{Binding TO_List_of_Numbers}" 
Header="Number of Boxes"
MinWidth ="200" 
CanUserResize="True" Width="*"></DataGridComboBoxColumn>

回答by matrixanomaly

To sum up what the previous issue was, thanks to Muds, and hours of trying, the Binding in the XAML was not properly done.

总结一下之前的问题,由于 Muds 和数小时的尝试,XAML 中的绑定没有正确完成。

In FruitDataGrid, this property should be written as ItemSource="{Binding}"this tells the XAML code to bind to whatever object the DataContext is assigned to in the code behind.

在 FruitDataGrid 中,应该编写此属性,因为ItemSource="{Binding}"它告诉 XAML 代码绑定到后面的代码中将 DataContext 分配给的任何对象。

After that, within the DataGrid.Column, this property is needed.

之后,在 DataGrid.Column 中,需要此属性。

Binding="{Binding Path=.}"

It had to be exactly that for me. lack of the dot or not enclosing it in quotes will not display the fruits.

对我来说必须完全如此。缺少点或不将其括在引号中将不会显示水果。

Thus, for clarity:

因此,为清楚起见:

In the XAML:

在 XAML 中:

<DataGrid x:Name="FruitDataGrid" 
 Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6" 
 HorizontalAlignment="Left" Width="1188" 
 AutoGenerateColumns="False"
 ItemSource="{Binding}"> 
<!-- If AutoGenerateColumns was true only the length is displayed.-->
<DataGrid.Columns>
<DataGridTextColumn 
      x:Name="fruitsDisplay" 
      Header="Fruits" MinWidth="450" 
      IsReadOnly="True" 
      Binding="{Binding Path=.}"/>    <!--Exactly like this -->
<DataGridComboBoxColumn 
       Header="Number of Boxes" 
       MinWidth ="200" 
       CanUserResize="True" Width="*" />
 </DataGrid.Columns>

And then in the codebehind (filename.xaml.xs)

然后在代码隐藏中(文件名.xaml.xs)

//Anywhere you plan to bind the list in my case FruitList
List<string> fruitList = new List<string>();
fruitList.add("Melon");
fruitList.add("Mango");
fruitList.add("Banana");

FruitDataGrid.DataContext = fruitList;

And now you'll have a very nice list displayed as a table. What killed 2 days of my time was the binding path should have a . (dot) right there, and I was binding to a string instead of an object (you literally bind to a string "fruitList" when you do Binding = {"fruitList"}. This amateur mistake stems from me insufficiently self-learning XAML.

现在您将有一个非常漂亮的列表显示为表格。杀死我两天时间的是绑定路径应该有一个 . (点)就在那里,我绑定到一个字符串而不是一个对象(当你执行 Binding = {"fruitList"} 时,你实际上绑定到一个字符串“fruitList”。这个业余错误源于我对 XAML 的自学不足。

Thanks again, Muds. I'll select yours as the answer because it helped me, and it feels weird accepting my own answer.

再次感谢,泥。我会选择你的作为答案,因为它对我有帮助,接受我自己的答案感觉很奇怪。