自定义标签不显示文本字符串

Zav*_*ael 1 c# label winforms

我需要制作自己的标签以保留一些值,这与显示给用户的值不同

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.RemoveControls.Add,感谢所有为他们的时间:)

WoL*_*lus 5

试试这个:

  1. 在标签类之外创建一个新委托:

    public delegate string LabelFormatDelegate( string val );
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将其添加到您的标签类:

    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)
  3. 在表单中放置一个新的公共标签(让我们将其命名为"label1")

  4. 转到Form1.Designer.cs并搜索"label1"声明.

  5. 将"标签"类型重命名为您自己的标签类型(例如:"MyLabel")

  6. 更改设计器代码上InitializeComponent函数上label的初始化代码,以匹配新类型"MyLabel"

    例:

    this.label1 = new Label();
    
    Run Code Online (Sandbox Code Playgroud)

    改成:

    this.label1 = new MyLabel();
    
    Run Code Online (Sandbox Code Playgroud)
  7. 在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)

这将使您的值/文本保持同步,但请记住不要手动设置"文本"属性.


And*_*tan 5

我的猜测是因为,由于您在构造函数中进行了工作,因此设计器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)

我认为,这解决了你的问题.