【问题标题】:How to handle the exceptions that thrown by a propertygrid?如何处理propertygrid抛出的异常?
【发布时间】:2011-08-16 11:02:48
【问题描述】:

我在 c# 中有一个 Winforms PropertyGrid,它控制从嵌入式系统获取和设置的数据。

我将有关设备的查询(GetFrequency、SetPowerLimit、SetACCurrent 等)编写为属性,以便我可以绑定数据,而无需为要创建的表单中的每个命令编写其他方法。

PropertyGrid 工作得非常好,我的意思是它显示了我需要的所有数据并让我更改它们的值。但当然并非总是如此。

由于必须运行的设备的这种黑盒情况,程序在某些时候会正常停止。 (即当您关闭设备时。)

例如,这是我必须经常从设备读取的值。 “思敏”

    [Category("Editable Values"), Description("Sets the minimum select...")]
    public Ampere Simin
    {
        get
        {...}
        set
        {...}
    }

在 Getter 和 Setter 中,我有这些 get 方法来建立 pc 和设备之间的连接。它们是我主要采取的异常的实际来源。

像这样

if (!_port.IsOpen)
        {
            throw new HuettingerException(Localisation.Error_PortClosed);
        }

或者这个

// Read first 4 bytes
            if (_port.Read(inputv, 0, 4) != 4)
            {
                throw new HuettingerException(Localisation.Error_NoConnection);
            }

所以我有三个抽象层,当我尝试读取一些数据时,我从机器端获取异常(如上图所示)。我试图在一开始就抓住其中的一些,比如

 public DeviceUI()
    {
        InitializeComponent();
        try
        {                
            propertyGrid1.SelectedObject = device;
        }
        catch (TimeoutException te) // i tried other exceptions too
        {
            MessageBox.Show(te.Message);
        }

在 winform 初始化时,但它不起作用。

我的问题是,如果是 Button 或 Textfield,我可以轻松捕获事件方法中的异常,但我不知道如何处理 PropertyGrid 抛出的异常。

有什么意见吗?

【问题讨论】:

  • 亲爱的第一个反对者,您至少可以发表评论。但是你不喜欢看到人们提高自己是吗?
  • 我不是反对者,我可能不会反对 - 但这可能是由于缺少一些代码来说明您如何使用 PropertyGrid。
  • 什么时候抛出这些异常?当用户在属性网格中编辑值或通过代码中的某些事件更新值时?
  • @iandotkelly,我的错。但是thanxalot的建议
  • @3yanlist1bos - 完全没问题。就像看到人们在这里得到很好的帮助一样。

标签: c# exception-handling propertygrid


【解决方案1】:

如果在转换(赋值)(即调用TypeConverter.ConvertFrom())到属性网格中的属性(例如,InvalidCastException)时抛出异常,那么您可以在TypeConverter 中捕获该属性。

class MyTypeConverter : TypeConverter
{
    public override bool ConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        try
        {
            return base.ConvertFrom(context, sourceType);
        }
        catch(Exception e)
        { 
            // Process the exception (for example, Log(e)) or Debug.Assert()
            throw;
        }
    }
}

// Using the TypeConverter in your class
class MyClass
{
    [ReadOnly(false)]
    [PropertyOrder(1)]
    [DisplayName("Property 1")]
    [TypeConverter(typeof(MyTypeConverter))]
    public int Property1
    {
        get;
        set;
    }
}

您还可以相应地覆盖基类TypeConverter 的其他方法。

通过您添加的示例,您似乎想要推断与设备通信失败的原因(端口未打开等)。那么为什么不在Device 类中设置一个属性或标志(例如ErrorCommunicationError)来告知是否发生了特定错误。

然后在TypeConverter 访问其他属性之前检查此属性,如果出错则直接从ConvertFrom() 返回而不调用base 实现。如果错误是可恢复的(在您的情况下似乎是通信错误),则允许用户重试,而不是抛出异常。

此外,如果您将设备参数直接映射到类,并且您有一个在属性网格中使用但不希望将其写入设备上的属性,则使用自定义属性对其进行标记(例如布尔值DeviceWritable)。在通信层(实际将值写入设备的地方),检查此自定义属性,如果将其设置为true,则写入设备,否则不写入设备。

【讨论】:

  • 非常感谢您的帮助!我认为它将使我摆脱额外的组合框、文本字段等所有这些问题。 ;) 但我仍然必须找到一种方法来摆脱这些直接来自我的设备的异常。
  • 我已经更新了答案以反映给出的示例,尽管我不确定为什么 device 会引发异常!如果出现错误,您应该在设备上有一个错误标志或寄存器来指示错误及其类型。
  • 设备抛出异常的原因主要是通信故障。因此,如果我读取的字节是意外的,那么要么我的机器没有打开,要么它运行缓慢,或者我的 RS232 电缆被烧毁,例如……所以在一些错误中,我确信即使是 DeviceWritable 方法也不会工作。我想我有你提到的寄存器。对于所有可预期的(预见的)错误,我有一种方法可以从设备中读取错误。但是对于出人意料的(非常愚蠢和错误的),我猜我必须抛出这些异常。
  • 那么例外是在PC和设备之间的communication期间,而不是在设备本身?如果正确,则不能在属性网格中处理通信(代表device)。通过从设备读取将值填充到 device 实例中应该由单独的 Communication 类完成。
  • 所以我需要的是除了 Device 和 Winform 之外的 Comm 类。这样我就可以在 Comm 中抛出异常并在 Device 中捕获。对吗?
猜你喜欢
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
  • 2013-07-24
  • 2022-11-25
  • 2021-12-22
  • 2013-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多