我需要制作自己的标签以保留一些值,这与显示给用户的值不同
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
但现在在表单构造函数中的id我用我的类替换控件
this.lbAttributeType = new LabelBean();
Run Code Online (Sandbox Code Playgroud)
然后在创建表单之后,但在显示之前,我通过setter设置文本
(this.lbAttributeType as LabelBean).Value = value;
this.lbAttributeType.Text = Transform(value);
Run Code Online (Sandbox Code Playgroud)
但在形式上我总是"label1"文本......它有什么问题?谢谢
UPDATE
我在这里添加了解决方案,以便更容易找到:
public class MyLabel : Label {
public MyLabel()
: base() {
}
public string Value {
set {
this.Text = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
和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";
}
}
Run Code Online (Sandbox Code Playgroud)
这个bug是在Controls.Remove
和Controls.Add
,感谢所有为他们的时间:)
试试这个:
在标签类之外创建一个新委托:
public delegate string LabelFormatDelegate( string val );
Run Code Online (Sandbox Code Playgroud)将其添加到您的标签类:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)在表单中放置一个新的公共标签(让我们将其命名为"label1")
转到Form1.Designer.cs并搜索"label1"声明.
将"标签"类型重命名为您自己的标签类型(例如:"MyLabel")
更改设计器代码上InitializeComponent函数上label的初始化代码,以匹配新类型"MyLabel"
例:
this.label1 = new Label();
Run Code Online (Sandbox Code Playgroud)
改成:
this.label1 = new MyLabel();
Run Code Online (Sandbox Code Playgroud)在Form_Load事件中,指定格式函数:
this.label1.ValueFormatter = new LabelFormatDelegate(this.Transform);
Run Code Online (Sandbox Code Playgroud)注意:您还需要从此处删除"文本"设置器调用:
(this.lbAttributeType as LabelBean).Value = value;
// this.lbAttributeType.Text = Transform(value);
Run Code Online (Sandbox Code Playgroud)
这将使您的值/文本保持同步,但请记住不要手动设置"文本"属性.
我的猜测是因为,由于您在构造函数中进行了工作,因此设计器InitializeComponent
自动生成的代码会覆盖控件实例,因为它很可能在初始化后调用.
如果该类是项目的一部分,您将在工具箱中找到它; 意思是你只需将新控件拖放到表单上代替现有控件 - 这就是你应该做的.
这可以确保设计器生成的属性属于您的LabelBean
类型,而不仅仅是Label
.
另外 - 您应该考虑更改您的Value
二传手,如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;
}
Run Code Online (Sandbox Code Playgroud)
2)继续使用您的子LabelBean
类型(通过我已经提到的设计器添加它) - 但是使用抽象来访问表单的Transform
方法:
public interface ITransformProvider
{
string Transform(string);
}
Run Code Online (Sandbox Code Playgroud)
使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,最后,使用WoLfulus的代码,但略有改变,你可以这样做:
public string Value
{
get
{
return value;
}
set
{
this.value = value;
var transformer = Transformer;
if(transformer != null) this.Text = transformer.Transform(value);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为,这解决了你的问题.