【问题标题】:.Net: Why we can't access to some properties of a control programmatically in winforms?.Net:为什么我们不能在 winforms 中以编程方式访问控件的某些属性?
【发布时间】:2010-05-15 10:05:13
【问题描述】:

.Net:为什么我们不能在 winforms 中以编程方式访问控件的某些属性?例如,不能通过代码访问 groupbox 的“Locked”属性。那么当我想以编程方式锁定它时,我可以做什么?使用 Enabled = False 会使其中的所有控件变灰,这不是我想要的。

有什么建议吗?

【问题讨论】:

  • 您想像设计器那样锁定您的控件,还是想简单地禁用它,但不让它变灰?

标签: .net winforms properties windows-forms-designer


【解决方案1】:

你知道 Locked 的真正含义吗?这不是一个正常的属性,无论如何都不会影响运行时,只有设计师。您可能应该去解决您要解决的问题。我可以向你保证:不需要“锁定”属性。

【讨论】:

  • 好吧,我不知道您是否使用 Vb6 开发了应用程序,但是有一个名为 frame 的控件,我们可以锁定它(以及其中的所有子控件),以便用户无法开始输入数据。但表格很清晰,不是灰色的。
  • 好的,抱歉,但我仍然认为您不应该这样做,因为这可能会破坏用户对您应用程序行为的期望。
【解决方案2】:

Locked 根本不是一个属性——它只是存储在资源文件中的一个值。锁定Form 控件会产生一个布尔资源值$this.Locked 设置为true。

其他一些属性使用IExtenderProvider 附加到控件,类似于 WPF 中的附加属性。例如,在将ToolTip 控件添加到设计器后,设计器将为所有控件显示属性ToolTip。要通过代码设置工具提示文本,您必须使用

this.toolTip1.SetToolTip(this.button1, "A button.");

因为控件没有ToolTip 属性。

还有更多类似ICustomTypeDescriptor 的机制导致设计器中显示的属性与实际为控件定义的属性不同。

有一个通用的解决方案可以禁用 WinForms 控件而不使它们变灰,但不幸的是我既不记得也找不到它...

【讨论】:

    【解决方案3】:

    你可以禁用它!!!!

    daveTextBox.Enabled = False
    

    这显然会改变控件的外观。如果您不想更改控件的外观,请覆盖按键事件处理程序以不执行任何操作。

    【讨论】:

    • 问题是关于不同的事情。
    • 我不同意 - 我对这个问题的理解是问题在于以编程方式锁定控件
    • 否。如果您只是禁用它(启用 = false),它及其中的所有子控件都将灰显。这不是我真正想要的。
    • @odiseh 这就是我在回复中所说的 - 这就是为什么我建议覆盖按键事件处理程序以不执行任何操作
    【解决方案4】:

    正如其他人已经指出的那样,您真正想要做的是将控件设为只读,但除了文本框和单选按钮之外,这可能相当复杂。

    下面是我为处理此类事情而编写的一些代码的摘录,但客户想要便宜而不是完美,所以我有一些灵活性,所以它可能不适合你。该方法只是由SetControlsReadonly(gb.Controls) 调用(假设一个名为 gb 的组框)。

    Private Sub SetControlsReadonly(ByVal ctrls As Windows.Forms.Control.ControlCollection)
      For Each ctrl As Control In ctrls
         ctrl.Enabled = True ' first enable everything so that it'll all look the same
         If TypeOf ctrl Is TextBox Then
            CType(ctrl, TextBox).ReadOnly = True
         ElseIf TypeOf ctrl Is Button Then
            CType(ctrl, Button).Enabled = False
         ElseIf TypeOf ctrl Is CheckBox Then
            CType(ctrl, CheckBox).AutoCheck = False
         ElseIf TypeOf ctrl Is ComboBox Then
            ctrl.Enabled = False 
            if ctrl.Tag IsNot Nothing Then
                ' call method that hides the combo and instead shows a readonly textbox in the same location containing the same data
            End If
         ElseIf TypeOf ctrl Is DateTimePicker Then
            ctrl.Enabled = False
         End If
         SetControlsReadonly(ctrl.Controls)
      Next
    End Sub
    

    【讨论】:

    • 您缺少处理所有其他控件类型的最终Else 块。如果您不包含它,并且有人在您的方法不知道如何处理的表单上放置了控件,则它不会被禁用。 - IMO最好设计出实现公共接口IHaveReadOnlyProperty(公开ReadOnly属性)的自己的控件类(来自标准控件)。然后,您的方法会检查控件是否支持该接口;如果是这样,它将暴露的ReadOnly 属性设置为false;否则,它会做次优的事情,即。它将Enabled 设置为false
    • 好吧,我并不是说您的设计不会更好(尤其是如果从头开始),但正如我所说,客户想要便宜而不是完美。但是,我不同意Else,如果您添加一个禁用其他所有功能的Else,您必须确保那里没有意外的控件(例如选项卡控件或包含文本框的组框等) 因为否则它不会按预期工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    相关资源
    最近更新 更多