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;

Может кто-то сталкивался с таким поведением? Заранее спасибо.
  • Вопрос задан
  • 3644 просмотра
Решения вопроса 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
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы