我需要让自己的标签保留一些值,这与显示给用户的值不同
public class LabelBean : Label {
private string value;
public LabelBean(string text = "", string value = ""): base() {
base.Text = text;
this.value = value;
}
public string Value {
get { return value; }
set { this.value = value; }
}
}
但现在在表单构造函数中的id我将控件替换为我的类
this.lbAttributeType = new LabelBean();
以及稍后创建表单之后,但在显示之前我通过setter设置文本
(this.lbAttributeType as LabelBean).Value = value;
this.lbAttributeType.Text = Transform(value);
但在形式上我总是“label1”文本......它有什么问题? 感谢
更新
我在这里添加了解决方案,以便更容易找到:
public class MyLabel : Label {
public MyLabel()
: base() {
}
public string Value {
set {
this.Text = value;
}
}
}
和Widnows.Forms.Label label1控件的表单
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.Controls.Remove(this.label1);
this.label1 = new MyLabel();
this.Controls.Add(this.label1);
(this.label1 as MyLabel).Value = "oh";
}
}
该错误发生在Controls.Remove
和Controls.Add
中,
感谢他们所有的时间:))
答案 0 :(得分:5)
试试这个:
在标签类之外创建一个新委托:
public delegate string LabelFormatDelegate( string val );
将此添加到您的标签类:
public LabelFormatDelegate ValueFormatter = null;
public string Value
{
get
{
return value;
}
set
{
this.value = value;
if (this.ValueFormatter != null)
{
this.Text = this.ValueFormatter(value); // change the label here
}
else
{
this.Text = value;
}
}
}
在表单中放置一个新的公用标签(让我们将其命名为“label1”)
转到Form1.Designer.cs并搜索“label1”声明。
将“标签”类型重命名为您自己的标签类型(例如:“MyLabel”)
更改设计器代码上 InitializeComponent 函数的标签初始化代码,以匹配新类型“MyLabel”
示例:
this.label1 = new Label();
更改为:
this.label1 = new MyLabel();
在Form_Load事件中,指定格式函数:
this.label1.ValueFormatter = new LabelFormatDelegate(this.Transform);
注意:您还需要从此处删除“文本”设置者调用:
(this.lbAttributeType as LabelBean).Value = value;
// this.lbAttributeType.Text = Transform(value);
这将使您的值/文本保持同步,但请记住不要手动设置“文本”属性。
答案 1 :(得分:5)
我的猜测是因为,由于您正在构造函数中进行工作,因此设计器自动生成的InitializeComponent
代码会覆盖控件实例,因为它很可能在初始化后调用。
如果该类是项目的一部分,您将在工具箱中找到它;意思是你可以简单地将新控件拖放到表单上代替现有控件 - 这就是你应该做的。
这可确保设计器生成的属性属于LabelBean
类型,而不仅仅是Label
。
另外 - 您应该考虑更改您的Value
setter,如WoLfulus所示(+1那里)
回应你对WoLfulus回答的评论 - 这里有几个选择:
1)如果表单在这里是'聪明'位 - 考虑只在其中编写一个辅助方法,并通过它设置标签的值,利用Tag
属性:
public void SetLabelBean(Label target, string value)
{
Label.Tag = value;
Label.Text = Transform(value);
}
public string GetLabelBean(Label target)
{
return target.Tag as string;
}
2)继续使用您的子类LabelBean
类型(通过我已经提到的设计器添加它) - 但是使用抽象来访问表单的Transform
方法:< / p>
public interface ITransformProvider
{
string Transform(string);
}
使用您所避免的Transform
方法,使您的表单类实现此接口。
现在,在LabelBean
课程中:
public ITransformProvider Transformer
{
get{
//searches up the control hierarchy to find the first ITransformProvider.
//should be the form, but also allows you to use your own container controls
//to change within the form. The algorithm could be improved by caching the
//result, invalidating it if the control is moved to another container of course.
var parent = Parent;
ITransformProvider provider = parent as ITransformProvider;
while(provider == null){
parent = parent.Parent;
provider = parent as ITransformProvider;
}
return provider;
}
}
然后,最后,使用WoLfulus的代码,但略有改变,你可以这样做:
public string Value
{
get
{
return value;
}
set
{
this.value = value;
var transformer = Transformer;
if(transformer != null) this.Text = transformer.Transform(value);
}
}
我认为,这个答案解决了你的问题。
答案 2 :(得分:2)
我同意WoLfulus和Andreas Zoltan,如果存在明确的逆向转换,我会在Text中添加对称功能:
public string Value
{
get { return value; }
set
{
if (this.value != value) {
this.value = value;
this.Text = Transform(value);
}
}
}
public override string Text
{
get { return base.Text; }
set
{
if (base.Text != value) {
base.Text = value;
this.value = TransformBack(value);
}
}
}
请注意if
检查,以避免无休止的递归。
编辑:
将标签分配给lbAttributeType
是不够的。您必须先删除控件集合中的旧标签,然后在分配后重新添加。
this.Controls.Remove(lbAttributeType); // Remove old label
this.lbAttributeType = new LabelBean();
this.Controls.Add(lbAttributeType); // Add new label
您的表单仍然显示旧标签!我为什么不早点看到它?