我在c#中有一个Winforms PropertyGrid,用于控制从嵌入式系统获取和设置的数据。
我将关于设备的查询(GetFrequency,SetPowerLimit,SetACCurrent e.c.)写为属性,这样我就可以绑定数据,而无需为我想要创建的Form中的每个命令编写另一个方法。
PropertyGrid非常好用,我的意思是它显示了我需要的所有数据并让我改变它们的值。但当然并非总是如此。
由于必须处理的设备的黑盒子位置,程序在某些点正常停止。 (即关闭设备时。)
例如,这是我必须经常从设备读取的值。 “斯民”
[Category("Editable Values"), Description("Sets the minimum select...")]
public Ampere Simin
{
get
{...}
set
{...}
}
在Getters和Setters中,我有这些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抛出的异常。
有什么意见吗?
答案 0 :(得分:2)
如果在转换(赋值)(即调用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类的其他方法。
通过示例,您已添加,看起来您希望推断出与设备通信失败的原因(端口未打开等)。那么为什么不在Error
类中设置一个属性或标志(例如,CommunicationError
或Device
),以告知是否发生了特定错误。
然后在访问其他属性之前TypeConverter
检查此属性,如果出错,则只需从ConvertFrom()
返回,而不调用base
实现。如果错误是可恢复的,在您的情况下似乎是通信错误,则允许用户重试,而不是抛出异常。
此外,如果您将设备参数直接映射到类上,并且您具有在属性网格中使用但不希望将其写入设备的属性,则使用自定义属性标记它(比如说)布尔DeviceWritable
)。在通信层(实际将值写入设备的位置)中,检查此自定义属性,如果它设置为true
,则写入设备,否则不写入设备。