【问题标题】:vb.net modifying values of custom attributes in a classvb.net 修改类中自定义属性的值
【发布时间】:2014-11-14 10:03:26
【问题描述】:

我有一个想法,可以在类中的属性上使用自定义属性,以便在 winforms 界面中进行数据绑定。例如,在包含无效数据的文本框上设置和更改背景色、前景色和工具提示。我发现我可以将 txtTest 的背景颜色等控件属性绑定到自定义属性,例如 BackColorAttr 装饰类中的属性,例如 Name,没有问题。属性值本身绑定到文本框的文本,双向绑定效果很好,初始背景色、前景色等都是按照我希望的方式从自定义属性的初始值设置的。我通过一个 BindingHelper 类来完成这一切,该类将所有编码简化为几个通用方法。

我被难住的地方是稍后操纵自定义属性的值。例如,将背景色更改为红色。我尝试过的任何方法似乎都不起作用。有没有人尝试过这样的事情,或者对我如何进行有一些指导?

【问题讨论】:

  • 你能展示一下你到目前为止所做的尝试吗?
  • 您的属性的属性是只读的。即使您可以在运行时更改它们,它们也不支持 INotifyPropertyChanged 接口,因此您的绑定永远不会刷新绑定到这些属性的值。
  • @Steve:这是 WinForms,因此没有 INotifyPropertyChanged 接口 - 至少本机如此。
  • @ncscoots:属性被设计为像常量一样操作——它们的值不会在运行时改变。如果您想在运行时控制值,我建议您实现 expando 属性(类似于 Tooltip 组件)。

标签: vb.net


【解决方案1】:

我不太了解第一部分或者绑定与颜色或属性有什么关系,但这不是Attributes 的工作方式。它们不是属性包装器,PropertiesMethodsTypes 不知道与它们关联的Attributes(以及反之)。它们是编译到程序集中的元数据。因此,您无法以任何有意义的方式更改该值。

测试类和测试属性:

Public Class BarState
    Inherits Attribute

    Public Property State As String

    Public Sub New(t As String)
        State = t
    End Sub
End Class

Public Class Foo

    <BarState("red")>
    Public Property Name As String

End Class

由于State是一个属性,测试我们是否可以设置它:

Dim f As New Foo

' get props for the Type
Dim pi As PropertyInfo = f.GetType.GetProperty("Name")

Dim attr = pi.GetCustomAttributes(GetType(BarState), False)

If attr.Length > 0 Then
    ' get prop info for the State property on the Attr Type
    Dim pa As PropertyInfo = attr(0).GetType.GetProperty("State")
    ' change it
    CType(attr(0), BarState).State = "GREEN"
    ' or 
    'pa.SetValue(attr(0), "GREEN", Nothing)

    ' print it  (prints "GREEN" but it does not persist)
    Console.WriteLine(CType(attr(0), BarState).State)
End If

'get the attr again as you might do next time thru
attr = pi.GetCustomAttributes(GetType(BarState), False)
' print the value   (Print "red")
Console.WriteLine(CType(attr(0), BarState).State)

第一个打印将是“绿色”,但这仅适用于这种情况 - 它不会持续存在。下次你得到它时,它会恢复为“红色”。由于属性 is 是一种类型,我们可以尝试使用被注释掉的pa.SetValue(attr(0), "GREEN", Nothing) 来通过反射来更改值。它仍然不会持续存在,因为“红色”被编译到程序集中,这就是您的起点。

您似乎可以为所有类型的所有属性保留一个字典或属性实例的集合。这可能会起作用,除非它们看起来都很相似,因此您必须创建一个哈希来跟踪哪个Attribute 实例与PropertyType 匹配。

而且您必须使该集合与底层实例对象保持同步。 Attribute 实例不会知道它来自的实例已经消失,因此状态设置应该恢复,因此您的 Attribute 管理器需要处理它。


您可能会研究“编织者”,它使用属性来标记事物(例如值范围),然后重写程序集以编织标记属性的范围检查。听起来有点像你是什么,我不知道他们可能会按照你描述的方式做些什么。

【讨论】:

  • 好的,谢谢各位。看起来好像我是在让一块砖游泳,哈哈。 Plutonix,实际上我很久以前在 VB6 中做过类似于你建议的事情。使用创建的记录集来保存接口内容,然后根据这些值操作接口。效果很好,所有代码都被封装了,yada yada yada。由于部分工作涉及定义我想要操作的控件属性,因此我希望在 .NET 中做一些类似的事情,只是不需要所有的工作。 :-)
  • 请查看Fody 等提供属性更改通知的织布工。这将提供一个活动,您可以在其中做很多您想做的事情。还有一个带有免费版本的商业版本。
  • 另外,如果这澄清了一些事情,你应该点击复选标记将其移开the unanswered list
猜你喜欢
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
相关资源
最近更新 更多