0
我有一個問題給你。我想在運行時在我的數據類中設置一些屬性的category屬性。我的數據類是自動生成的,我無法在設計時生成期間設置類別。設置屬性在運行時屬性的類別
我已經在運行時使用以下設置屬性的類別,不幸的是,當我設置第二個參數的category屬性也改變了第一個參數的類別....我缺少什麼?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Diagnostics;
namespace myApplication
{
public partial class Form1 : Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.SuspendLayout();
//
// propertyGrid1
//
this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid1.Location = new System.Drawing.Point(0, 0);
this.propertyGrid1.Name = "propertyGrid1";
this.propertyGrid1.Size = new System.Drawing.Size(284, 262);
this.propertyGrid1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.propertyGrid1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PropertyGrid propertyGrid1;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Object selectedObject = new Shape()
{
x = 100,
y = 200
};
var x = TypeDescriptor.GetProperties(selectedObject)["x"].Attributes;
CategoryAttribute attrx = (CategoryAttribute)x[typeof(CategoryAttribute)] as CategoryAttribute;
FieldInfo category_x = attrx.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
if (category_x != null)
{
if (category_x.FieldType == "string".GetType())
{
category_x.SetValue(TypeDescriptor.GetProperties(selectedObject)["x"].Attributes[typeof(CategoryAttribute)], "A_Category_For_x");
}
}
Debug.Assert(attrx.Category == "A_Category_For_x");
var y = TypeDescriptor.GetProperties(selectedObject)["y"].Attributes;
CategoryAttribute attry = (CategoryAttribute)y[typeof(CategoryAttribute)] as CategoryAttribute;
FieldInfo category_y = attry.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
if (category_y != null)
{
if (category_y.FieldType == "string".GetType())
{
category_y.SetValue(TypeDescriptor.GetProperties(selectedObject)["y"].Attributes[typeof(CategoryAttribute)], "A_Category_For_y");
}
}
Debug.Assert(attrx.Category == "A_Category_For_x"); // here is stops... why is category for x changed????
Debug.Assert(attry.Category == "A_Category_For_y");
propertyGrid1.SelectedObject = selectedObject;
// Force the PropertyGrid to redraw itself
propertyGrid1.Refresh();
}
}
public partial class Shape : System.ComponentModel.INotifyPropertyChanged
{
private short yField;
private short xField;
[System.Xml.Serialization.XmlAttributeAttribute()]
public short y
{
get
{
return this.yField;
}
set
{
if ((this.yField != null))
{
if ((yField.Equals(value) != true))
{
this.yField = value;
this.OnPropertyChanged("y");
}
}
else
{
this.yField = value;
this.OnPropertyChanged("y");
}
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public short x
{
get
{
return this.xField;
}
set
{
if ((this.xField != null))
{
if ((xField.Equals(value) != true))
{
this.xField = value;
this.OnPropertyChanged("x");
}
}
else
{
this.xField = value;
this.OnPropertyChanged("x");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
System.ComponentModel.PropertyChangedEventHandler handler = this.PropertyChanged;
if ((handler != null))
{
handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
更新/額外信息 我認爲.NET先後爲的CategoryAttribute相同的實例時,它沒有明確設置。如果我設置它,我可以改變每個屬性的類別,如下所示:
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System;
using System.Linq;
namespace CSharpConsoleApplication
{
public static class Program
{
public static void Main()
{
Object selectedObject = new myDataClass
{
x = 100,
y = 200
};
CategoryAttribute attrx =
selectedObject.GetType().GetProperty("x").GetCustomAttributes(typeof(CategoryAttribute), false).Single() as
CategoryAttribute;
FieldInfo category_x = attrx.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
if (category_x != null)
{
if (category_x.FieldType == "string".GetType())
{
category_x.SetValue(attrx, "categoryX");
}
}
Debug.Assert(attrx.Category == "categoryX");
CategoryAttribute attry =
selectedObject.GetType().GetProperty("y").GetCustomAttributes(typeof(CategoryAttribute), false).Single() as
CategoryAttribute;
FieldInfo category_y = attry.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
if (category_y != null)
{
if (category_y.FieldType == "string".GetType())
{
category_y.SetValue(attry, "categoryY");
}
}
Debug.Assert(attrx.Category == "categoryX"); //success now!
Debug.Assert(attry.Category == "categoryY");
}
public partial class myDataClass
{
[CategoryAttribute("Test")]
public int x { get; set; }
[CategoryAttribute("Default")]
public int y { get; set; }
}
}
}
正如你所看到的,這是成功的!不幸的是,我的部分類myDataClass是自動生成的,我必須在每次生成後手動設置CategoryAttribute。我不想這樣做,但將其設置在運行時...
可能是這個額外的信息可以幫助?