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

时间:2012-01-13 13:49:25

标签: c# winforms label

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

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

3 个答案:

答案 0 :(得分:5)

试试这个:

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

    public delegate string LabelFormatDelegate( string val );
    
  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;
            }
        }
    }
    
  3. 在表单中放置一个新的公用标签(让我们将其命名为“label1”)

  4. 转到Form1.Designer.cs并搜索“label1”声明。

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

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

    示例:

    this.label1 = new Label();
    

    更改为:

    this.label1 = new MyLabel();
    
  7. 在Form_Load事件中,指定格式函数:

    this.label1.ValueFormatter = new LabelFormatDelegate(this.Transform);
    
  8. 注意:您还需要从此处删除“文本”设置者调用:

    (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

您的表单仍然显示旧标签!我为什么不早点看到它?