[英]Twoway binding datagrid wpf xaml
public partial class TechnicalPropertiesU_Var : Window
{
public TechnicalPropertiesU_Var()
{
InitializeComponent();
List<Myclass> myclassList = new List<Myclass>();
myclassList.Add(new Myclass() { IA = 0, IB = 0, IC = 0, ID = 0, IE = 0, IF = 0, IF = 0 });
MyGrid.ItemsSource = myclassList;
}
}
我的窗口 Xaml:
<Grid>
<DataGrid x:Name="MyGrid" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Argument Name"></DataGridTextColumn>
<DataGridTextColumn Header="Argument Value"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
模型类
public class Myclass
{
private int iA;
private int iB;
private int iC;
private int iD;
private int iE;
private int iF;
private int iG;
public int IA{get=>iA; set=>iA =value;}
public int IB{get=>iB; set=> iB =value;}
public int IC{get=>iC; set=> iC =value;}
public int ID{get=>iD; set=> iD =value;}
public int IE{get=>iE; set=> iE =value;}
public int IF{get=>iF; set=> iF =value;}
public int IG{get=>iG; set=> iG =value;}
}
如何获取数据网格字段中的特定列。 请提供任何样品
如果您尝试获得的结果是一个包含两列的表格(请参阅您的图片),那么我猜您显然混淆了行和列。 您的数据类必须具有两个属性: ArgumentName
和ArgumentValue
。 您必须知道每个项目(或MyClass
每个实例)都将显示为一行。 现在,为每一行创建MyClass
一个实例并将其添加到源集合中。 将DataGridTextColumn.Binding
属性绑定到MyClass
模型的列的相关属性。
以下示例将显示图像中的表格:
MyTableClass.cs
public class MyTableClass : INotifyPropertyChanged
{
public MyTableClass(int argumentName, int argumentValue)
{
this.ArgumentName = argumentName;
this.ArgumentValue = argumentValue;
}
private int argumentName;
private int argumentValue;
public int ArgumentName{get=>argumentName; set{argumentName=value; NotifyPropertyChanged();}}
public int ArgumentValue{get=>argumentValue; set{argumentValue=value; NotifyPropertyChanged();}}
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
TechnicalPropertiesU_Var.xaml.cs
public partial class TechnicalPropertiesU_Var : Window
{
public TechnicalPropertiesU_Var()
{
InitializeComponent();
List<MyTableClass> myTableClasses = new List<MyTableClass>();
myTableClasses.Add(new MyTableClass() { ArgumentName = "IA", ArgumentValue = 5 });
myTableClasses.Add(new MyTableClass() { ArgumentName = "IB", ArgumentValue = 3 });
myTableClasses.Add(new MyTableClass() { ArgumentName = "IC", ArgumentValue = 2 });
myTableClasses.Add(new MyTableClass() { ArgumentName = "ID", ArgumentValue = 0 });
MyGrid.ItemsSource = myTableClasses;
}
}
我的窗口.xaml
<Grid>
<DataGrid x:Name="MyGrid" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Argument Name" Binding="{Binding ArgumentName}"></DataGridTextColumn>
<DataGridTextColumn Header="Argument Value" Binding="{Binding ArgumentValue}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
解决您的评论:“我不想绑定参数名称和参数值属性。我想绑定我自己的 CLR 属性。因为我有 250 个变量。”
我不必理解你的意图来告诉你这是一个坏主意。 一个类不应该有 250 个属性。 您的图像清楚地表明,并非所有 250 个属性都具有关系,但只有两个具有关系。
在您的情况下,数据包含一个字符串值,例如"IA"
和一个数值,例如5
。 您应该更改您的课程以反映这一点。
您应该知道,在常见的关系数据库设计中,数据记录由一行表示。 每行是一个对象,该行的每一列是该对象的属性。 DataGrid´ is designed with the same intention: each row is an item of the
DataGrid.ItemsSource` 的DataGrid´ is designed with the same intention: each row is an item of the
。 每个项目都是一个单独的实例。 通常从左到右阅读任何表格,例如产品的价格表,其中一行的每一列预计与单个数据项(例如产品)相关。
我强烈建议您放弃最初的意图并更改数据类以反映数据的关系,例如示例的MyTableClass
反映具有两个属性(列)的数据对象(行)的关系。
您尝试做的事情没有多大意义,尤其是从维护的角度来看。 您显然有 250 个要列出的变量。 如果此列表被缩短或扩展,并且您现在有 2389 个变量(夸大了,但只是为了重点)怎么办。 你会拔出你的头发试图保持它。
相反,您应该更多地了解类结构、更可能的数据库并尝试找到一个共同的模式。 您拥有的每个“事物”都是一个基于整数的项目。 但是每个“事物”都有相应的用途,或描述,例如您的 IA、IB、IC 等。
我建议您考虑以下事项。 我已经制作了一个带有事物列表的枚举器。 下面的示例,但我只有 IA-IG 的项目。 出于示例目的,我还提供了与其中两件事相关的描述。
public enum my250Things
{
IA,
IB,
[Description("this is item C")]
IC,
ID,
IE,
[Description("testing F description")]
IF,
IG
}
所以,现在在你的代码中,如果我有一个基于“my250Things”类型的变量,我可以通过它的枚举来引用它以了解它代表什么。
回到你的数据网格。 由于要显示的所有记录各占一行,并显示相应的变量名称上下文(IA、IB 等)及其包含的值,因此我创建了一个类。 这个类实际上有3个属性。 一个显示值、一个显示整数和它基于的原始枚举值。 以下。
public class YourCommonThings : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _yourShowValue;
public string YourShowValue
{
get { return _yourShowValue; }
set { _yourShowValue = value;
NotifyPropertyChanged(); }
}
private int _yourIntValue;
public int YourIntValue
{
get { return _yourIntValue; }
set
{
_yourIntValue = value;
NotifyPropertyChanged();
}
}
private my250Things _theOriginalEnum;
public my250Things TheOriginalEnum
{
get { return _theOriginalEnum; }
set
{
_theOriginalEnum = value;
NotifyPropertyChanged();
}
}
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
现在,我想填充我想要呈现给用户的内容列表。 由于枚举让我知道我试图跟踪的“事物”,我可以使用它来填充列表,以及它的描述(如果适用)。 如果没有,则默认使用枚举本身的字符串表示形式。 我为演示创建了一个简单的窗口“Stack1”,创建了一个公共属性,用于将数据列表绑定到枚举并根据枚举自动填充。
您将需要窗口的 .cs 文件顶部的这些“使用”引用
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
这是窗口代码隐藏中的代码
public partial class Stack1 : Window
{
// first, making a public property as a list of the things I want to present
public List<YourCommonThings> BindToThisListOfThings { get; set; }
// the name of my window is called "Stack1" and this is the constructor of the window
public Stack1()
{
// start by declaring a new list of things based on the class
BindToThisListOfThings = new List<YourCommonThings>();
// Now, we can dynamically create a list of all the "things" you are trying to present
// into your data grid. In this case, I am going through an enumerator list, but could
// also be done if the list of things was stored in a database (for example) and you
// queried from that, but that is a different question / option.
foreach(my250Things oneThing in typeof( my250Things ).GetEnumValues() )
{
// creating one instance of whatever your enum underlying thing is and
// default setting the properties within the class instance for the parts
// that are within the { }
// the ".ToString()" portion will get your "IA","IB", ...
// I can also add in to store the original enum value while I'm at it,
// even though not showing to the end user in the screen.
var justOne = new YourCommonThings
{ YourShowValue = oneThing.ToString(),
YourIntValue = 0,
TheOriginalEnum = oneThing };
// and you can optionally just for sake of example purposes associate a description
// to an enum value and pull THAT instead...
string description = GetEnumDescription(oneThing);
if (!string.IsNullOrWhiteSpace(description))
justOne.YourShowValue = description;
// Now, add to your list
BindToThisListOfThings.Add(justOne);
}
// Now, you have your list prepared and ready to go for binding to
DataContext = this;
// and finish initializing the rest of the form.
InitializeComponent();
}
// this static method is used to get the "description" component
// out of the enumeration declaration IF such a description is declared.
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
if (attributes != null && attributes.Any())
return attributes.First().Description;
return value.ToString();
}
}
最后,在表单的 xaml 中,我将数据网格绑定到从枚举准备的事物列表。
<DataGrid AutoGenerateColumns="False" VerticalContentAlignment="Stretch"
ItemsSource="{Binding BindToThisListOfThings, NotifyOnSourceUpdated=True}">
<DataGrid.Columns>
<DataGridTextColumn Header="Argument Name" Binding="{Binding YourShowValue}" Width="125" />
<DataGridTextColumn Header="Argument Value" Binding="{Binding YourIntValue}" Width="125" />
</DataGrid.Columns>
</DataGrid>
现在,在窗体/窗口中,或任何定义了 MVVM 模式的地方(此时有疑问),但无论如何,无论您计划保存数据,您都可以循环浏览事物列表,并获取其各自的事物和描述保存您计划的任何地方,但这在您的问题中未披露以进一步申请。
public void SaveData()
{
foreach( var oneThing in BindToThisListOfThings )
{
// Here, you can refer to
// oneThing.YourShowValue
// oneThing.YourIntValue
// oneThing.TheOriginalEnum
}
}
祝你好运。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.