在没有 DesignerSerializationVisibilityAttribute 的情况下序列化自定义控件的命名
Serializing custom control's naming without DesignerSerializationVisibilityAttribute
问题
我试图创建一个自定义控件,它只包含一个标签。但是,我希望将标签的文本更改为设计时自定义控件的名称 属性。
这是我的自定义控件 class 的样子:
public partial class Tile : UserControl
{
public Tile()
{
InitializeComponent();
}
[Browsable(true)]
public override string Text { get => label1.Text; set => label1.Text = value; }
}
如您所见,我已经覆盖了 UserControl 的 Text
属性,它会在 Name
更新后立即更新 Label 的文本,这在结束没有工作。发生的事情是,当我从工具箱中拖动控件以形成标签时,标签得到了预期的更新,但在我构建项目的那一刻,设计器得到了刷新,标签的文本丢失了。
我试过的
DesignerSerializationAttribute
通过 Google 我找到了 Whosebug 上给出的解决方案
Hans Passant 本身使用
DesignerSerializationAttribute(DesignerSerializationVisibility.Visible)
可以解决问题,因为给定 Text
属性 的值将
被保留在初始化代码中,这在初始化代码中似乎是有效的
一开始就迷路了(价值并没有持续存在并迷失在设计师身上
重绘)。
所以我把我的属性改成了这样:
[Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text { get => label1.Text; set => label1.Text = value; }
做这样的改变实际上解决了这个问题,现在即使我构建项目它也能正常工作。
我发现了什么
虽然我的问题已经解决了,但后来我开始寻找另一种方式
接近相同的结果。
在对我的代码进行更多试验时,我发现如果我创建
另一个 属性 公开标签的 Text
属性 并更新
它使用 overridden Text
属性 它的工作原理与它完全一样
正在使用 DesignerSerializationAttribute
.
新代码如下所示:
[Browsable(false)]
public string LabelText { get => label1.Text; set => label1.Text = value; }
[Browsable(true)]
public override string Text { get => LabelText; set => LabelText = value; }
我想知道
为什么这有效(即使没有 DesignerSerializationVisibility
):
Text
---->LabelText
---->标签的Text
我现在可能会问一些非常明显的问题,但几个小时以来我一直在阅读它,这让我有点困惑。
如果你查看 UserControl
的 source code,你可以看到 Text
属性 被设计者标记为不可序列化,所以基本上属性 将在您关闭表格后丢失:
[Browsable(false),
EditorBrowsable(EditorBrowsableState.Never),
Bindable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text {
get {
return base.Text;
}
set {
base.Text = value;
}
}
但在您的替代解决方案中,设计器会将 LabelText
序列化为 属性,然后将其值 return 用作 Text
。这就是它起作用的原因。
问题
我试图创建一个自定义控件,它只包含一个标签。但是,我希望将标签的文本更改为设计时自定义控件的名称 属性。
这是我的自定义控件 class 的样子:
public partial class Tile : UserControl
{
public Tile()
{
InitializeComponent();
}
[Browsable(true)]
public override string Text { get => label1.Text; set => label1.Text = value; }
}
如您所见,我已经覆盖了 UserControl 的 Text
属性,它会在 Name
更新后立即更新 Label 的文本,这在结束没有工作。发生的事情是,当我从工具箱中拖动控件以形成标签时,标签得到了预期的更新,但在我构建项目的那一刻,设计器得到了刷新,标签的文本丢失了。
我试过的
DesignerSerializationAttribute
通过 Google 我找到了 Whosebug 上给出的解决方案 Hans Passant 本身使用
DesignerSerializationAttribute(DesignerSerializationVisibility.Visible)
可以解决问题,因为给定Text
属性 的值将 被保留在初始化代码中,这在初始化代码中似乎是有效的 一开始就迷路了(价值并没有持续存在并迷失在设计师身上 重绘)。所以我把我的属性改成了这样:
[Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public override string Text { get => label1.Text; set => label1.Text = value; }
做这样的改变实际上解决了这个问题,现在即使我构建项目它也能正常工作。
我发现了什么
虽然我的问题已经解决了,但后来我开始寻找另一种方式 接近相同的结果。
在对我的代码进行更多试验时,我发现如果我创建
另一个 属性 公开标签的 Text
属性 并更新
它使用 overridden Text
属性 它的工作原理与它完全一样
正在使用 DesignerSerializationAttribute
.
新代码如下所示:
[Browsable(false)]
public string LabelText { get => label1.Text; set => label1.Text = value; }
[Browsable(true)]
public override string Text { get => LabelText; set => LabelText = value; }
我想知道
为什么这有效(即使没有 DesignerSerializationVisibility
):
Text
---->LabelText
---->标签的Text
我现在可能会问一些非常明显的问题,但几个小时以来我一直在阅读它,这让我有点困惑。
如果你查看 UserControl
的 source code,你可以看到 Text
属性 被设计者标记为不可序列化,所以基本上属性 将在您关闭表格后丢失:
[Browsable(false),
EditorBrowsable(EditorBrowsableState.Never),
Bindable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text {
get {
return base.Text;
}
set {
base.Text = value;
}
}
但在您的替代解决方案中,设计器会将 LabelText
序列化为 属性,然后将其值 return 用作 Text
。这就是它起作用的原因。