Ethiopian
@Ethiopian

WPF «проглатывает» исключения. Куда копать?

Приветствую. Столкнулись в проекте с проблемой: есть WinForms фрейм, на котором в ElementHost добавляется WPF контрол:
var child = new SomeWPFControl();
var host = new ElementHost
                {
                    Child = child,
                    Dock = DockStyle.Fill
                };
 Controls.Add(host);

Работает прекрасно, но беда в том, что если внутри контрола происходит исключение, то оно просто проглатывается и наверх ничего не выходит. В самом контроле не хотелось бы городить блоки try/catch, т.к. в проекте есть глобальбая обработка исключений с диалоговым окном для юзера. Гуглеж вывел на совет добавить обработчик события исключения на сам контрол, при добавлении его во фрейм и в нем уже предавать его дальше:
child.Dispatcher.UnhandledException += DispatcherUnhandledException;

private void DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            //Вместо окна планировалось пробросить исключение дальше, 
            //но до этого обработчика событие не добирается.
            MessageBox.Show("Произошло необработанное исключение: " + e.Exception.Message, "Exception");
            e.Handled = true;
        }

Эффекта нет, исключения не доходят до этого обработчика.

В App.xaml.cs указан глобальный обработчик, он тоже не ловит эти исключения:
Application.Current.DispatcherUnhandledException +=  handleUIThreadException;

Может кто-то сталкивался с таким поведением? Заранее спасибо.
  • Вопрос задан
  • 3622 просмотра
Решения вопроса 1
Ethiopian
@Ethiopian Автор вопроса
Временно решили проблему следующим образом:
// Создаем класс, который будет слушать отладочную информацию
 public class BindingErrorListener : TraceListener
    {
        public BindingErrorListener()
        {
            // Ловим только ошибки
            PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Error;
            this.Filter = new SourceFilter("System.Windows.Data");
        }

        // Этот метод вызываем при инициализации окна, чтобы начать слушать поток
        public static void Listen()
        {
            PresentationTraceSources.DataBindingSource.Listeners.Add(new BindingErrorListener());
        }
        public override void Write(string message) { }

        // Этот метод вызывается при попытке вывести в отладчик сообщение об ошибке привязки
        public override void WriteLine(string message)
        {
                // Бросаем ислючение с информацией об ошибке
                throw new Exception(message);
        }
    }


Если у кого-то есть более изящное решение, будем очень рады увидеть.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Sumor
Ошибки Binding проглатываются — это действительно фишка WPF. Они пишутся в выход отладчика с описанием ошибки.
Для отлова ошибок можно использовать событие BindingComplete, примерно, как это описано у Microsoft.
Пример отлова ошибок Binding.

Помимо этого есть интересный механизм проверки значений ValidationRule.
Пример использования ValidationRule
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы