Domanda

Ho la seguente situazione in cui un'eccezione lanciata in un ViewModel non bolle su Application_unHandlexception in app.xaml.cs.

Ho un ObservableCollection nel ViewModel legato agli elementiurceProperty in un combobox. La propropertà selezionata del combobox è legata a una proprietà nel ViewModel.

Quando gli utenti selezionano una voce in ComboBox, la proprietà viene chiamata correttamente nel ViewModel. Viene eseguito un po 'di logica e un'altra proprietà (Call It Property2) è impostata nel ViewModel. Tuttavia, esiste un'eccezione non gestita in Property2. L'eccezione è solo "scompare": non viene sollevata sul thread dell'interfaccia utente.

Qualche suggerimento su come risolvere generalmente questo problema o un approccio per catturare eccezioni su qualsiasi thread?

Si noti che abbiamo un framework MVVM su misura. All'inizio, ho pensato che fosse un problema con il nostro framework. Dopo molte ore di debug, ho deciso di scaricare PRISM4 (http://www.microsoft.com/download/en/confirmation.aspx?id=4922) e vedere se uno scenario simile potrebbe essere riprodotto nell'applicazione di riferimento StockTrader.

Posso riprodurre esattamente lo stesso scenario! Sarei felice di fornire dettagli su come impostare l'eccezione in Prism4.

Qualsiasi aiuto o puntatori su un approccio generale per catturare tutte le eccezioni non gestite in Silverlight è molto apprezzato.

Saluti, Travis

È stato utile?

Soluzione

Poiché il runtime consente di utilizzare le eccezioni a fini di convalida, l'operazione di recupero del valore di runtime è in un grande blocco di try-catch.

Dai un'occhiata a System.Windows.Data.BindingExpression.UpDateValue () in Ilspy per i dettagli (in System.Windows. La versione WPF potrebbe essere più facile da capire (Aggiornamento)).

Non penso che sia possibile personalizzare il comportamento del runtime per ripetere le tue eccezioni. Dal codice puoi vedere che ritocca alcuni critici.

   OutOfMemoryException, StackOverflowException, AccessViolationException, ThreadAbortException

Dal momento che altre eccezioni non sono ritoccanti, sono, in effetti, gestite.

Penso che la tua soluzione sia quella di catturare la traccia o avere la tua gestione delle eccezioni nei setter di proprietà.

Altri suggerimenti

Di recente ho trovato il modo in cui catturare tutte le eccezioni vincolanti in tutti i set di proprietà (funziona in Silverlight 5):

public class Helper
{
    public static void EnableBindingExceptions(FrameworkElement element)
    {
        const BindingFlags flags = BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Static;
        var fields = element.GetType().GetFields(flags).Where(x => x.FieldType == typeof(DependencyProperty));
        foreach (var field in fields)
        {
            var dp = (DependencyProperty)field.GetValue(null);
            var be = element.GetBindingExpression(dp);
            if (be == null) continue;

            element.SetBinding(dp, new Binding(be.ParentBinding) {ValidatesOnExceptions = true, ValidatesOnNotifyDataErrors = true});
            element.BindingValidationError += OnBindingValidationError;
        }

        var childrenCount = VisualTreeHelper.GetChildrenCount(element);
        for (var i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;
            if (child == null) continue;

            EnableBindingExceptions(child);
        }
    }

    private static void OnBindingValidationError(object sender, ValidationErrorEventArgs e)
    {
        throw new TargetInvocationException(e.Error.Exception);
    }
}

Quindi invoca il metodo abilita per ogni visione:

public partial class MyView : UserControl
{
    public MyView()
    {
        InitializeComponent(); 
        Helper.EnableBindingExceptions(this);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top