Как обрабатывать исключения, которые выдает сетка свойств? - PullRequest
1 голос
/ 16 августа 2011

У меня есть таблица свойств Winforms в c #, которая управляет данными, полученными и настроенными из встроенной системы.

Я написал запросы об устройстве (GetFrequency, SetPowerLimit, SetACCurrent и т. Д.) В качестве свойств, чтобы я мог связывать данные, не записывая другой метод для каждой команды внутри формы, которую я хочу создать.

PropertyGrid работает очень хорошо, я имею в виду, что он показывает все данные, которые мне нужны, и позволяет мне изменять их значения. Но не всегда конечно.

Из-за этого черного ящика устройства, на котором приходится работать, программа в некоторых точках обычно останавливается. (т.е. когда вы выключаете устройство.)

Например, вот значение, которое мне приходится часто читать с устройства. "Симин"

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

Внутри геттеров и сеттеров у меня есть эти методы get, которые устанавливают связь между компьютером и устройством. И они являются фактическим источником исключений, которые я беру в основном.

Как это

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, но это не сработало.

Моя проблема в том, что если бы это была кнопка или текстовое поле, я мог бы легко перехватывать исключения в методах событий, но я не имею ни малейшего представления об обработке исключения, которое выдается PropertyGrid.

Есть мнения?

1 Ответ

2 голосов
/ 17 августа 2011

Если исключение выдается при преобразовании (присвоении значения) (т. Е. При вызове 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, затем выполните запись на устройство, в противном случае не выполняйте запись на устройство.

...