question

Anja-7727 avatar image
0 Votes"
Anja-7727 asked Anja-7727 commented

Try Catch in Wpf

I'm normally used to asp.net where there is an method, where I can test on try/catch.

But here in Wpf I cannot figure out what to do. It isn't when I have a button and do some code in the codebehind part. That I can do. But when loading the page/usercontrol

When loading the list in the ListView - I load by Binding Categories_GetActive But what to do, if that get an error?

This I do in the designer and not the codebehind, so how do I make an try/catch so I can throw the exception to see what is wrong? And yes I have to ask, because I do not know how to change the list, so it throws an exception. So please forgive me :-) In the UserControl I have the following code

 <UserControl x:Class="Views.Account.AccountObsoleteView"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:Views.Account"
              xmlns:viewModel = "clr-namespace:ViewModel.Account;assembly=ViewModel"
              mc:Ignorable="d" 
              d:DesignHeight="550" d:DesignWidth="1000">
     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="585" />
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="989" />
         </Grid.ColumnDefinitions>
    
         <!--<Border BorderThickness="1" BorderBrush="Red" />-->
         <TabControl Grid.Row="0" Grid.Column="0" Style="{StaticResource tabControlSmall}">
             <TabItem Header="Aktive" Style="{StaticResource tabItemSmall}" >
                 <!--Tab aktive/inaktive-->
                 <Grid>
                     <Grid.RowDefinitions>
                         <RowDefinition Height="537" />
                     </Grid.RowDefinitions>
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition Width="475" />
                         <ColumnDefinition Width="490" />
                     </Grid.ColumnDefinitions>
                     <!--<Border BorderThickness="1" BorderBrush="Blue" Grid.ColumnSpan="2" />-->
                     <!--Row 0 Venstre halvdel-->
                     <ListView ItemsSource="{Binding Categories_GetActive}" Grid.Row="0" Grid.Column="0">
                         <ListView.View>
                             <GridView>
                                 <GridViewColumn Header="Id" Width="50"  DisplayMemberBinding="{Binding CategoryId}"/>
                                 <GridViewColumn Header="Navn" Width="320"  DisplayMemberBinding="{Binding CategoryName}"/>
                                 <GridViewColumn Header="Global" Width="50"  DisplayMemberBinding="{Binding CategoryIsGlobal}"/>
                             </GridView>
                         </ListView.View>
                     </ListView>
                     <Grid Grid.Row="0" Grid.Column="1">
                     <!--Row 0 højre halvdel-->
                         <Grid.RowDefinitions>
                             <RowDefinition Height="50" />
                             <RowDefinition Height="35" />
                             <RowDefinition Height="10" />
                             <RowDefinition Height="200" />
                             <RowDefinition Height="400" />
                         </Grid.RowDefinitions>
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="487" />
                         </Grid.ColumnDefinitions>
                            
                         <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" Width="480">
                             <Label x:Name="LblMessageCategoryActive" Content="" BorderThickness="1" Height="50" />
                         </StackPanel>
                         <!--<Border BorderThickness="1" BorderBrush="Red" Grid.ColumnSpan="2" Grid.RowSpan="2" />-->
                         <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Top" Width="190">
                                
                             <!--Row 1-->
                             <Button x:Name="BtnCategoryActiveInactive" Content="Inaktiv" Width="75" Margin="25 0 0 0" />
                             <Button x:Name="BtnCategoryActiveNew" Content="Ny" Width="75" Margin="5 0 0 0" />
                         </StackPanel>
                         <StackPanel Margin="10" Orientation="Vertical" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Top" Width="427">
                             <Grid VerticalAlignment="Top" HorizontalAlignment="Right">
                                 <Grid.RowDefinitions>
                                     <RowDefinition Height="5" />
                                     <RowDefinition Height="35" />
                                     <RowDefinition Height="35" />
                                     <RowDefinition Height="35" />
                                     <RowDefinition Height="35" />
                                     <RowDefinition Height="35" />
                                     <RowDefinition Height="*" />
                                 </Grid.RowDefinitions>
                                 <Grid.ColumnDefinitions>
                                     <ColumnDefinition Width="255" />
                                     <ColumnDefinition Width="90" />
                                     <ColumnDefinition Width="200" />
                                     <ColumnDefinition Width="25" />
                                 </Grid.ColumnDefinitions>
                                 <!--<Border BorderThickness="1" BorderBrush="Blue" Grid.ColumnSpan="3" Grid.RowSpan="2" />-->
                                 <!--Row 0-->
                                 <Label Content="" Grid.Row="0" Grid.Column="0" />
                                 <!--Row 1-->
                                 <Rectangle Grid.Row="1" Grid.Column="1" Fill="#d3d0d0" />
                                 <Rectangle Grid.Row="1" Grid.Column="2" Fill="#d3d0d0" />
                                 <Rectangle Grid.Row="1" Grid.Column="3" Fill="#d3d0d0" />
                                 <Label Content="Id:" Grid.Row="1" Grid.Column="1" HorizontalContentAlignment="Right" />
                                 <Label x:Name="LblCategoryActiveId" Content="" Grid.Row="1" Grid.Column="2" HorizontalContentAlignment="Left" />
    
                                 <!--Row 2-->
                                 <Rectangle Grid.Row="2" Grid.Column="1" Fill="#e3e1e1" />
                                 <Rectangle Grid.Row="2" Grid.Column="2" Fill="#e3e1e1" />
                                 <Rectangle Grid.Row="2" Grid.Column="3" Fill="#e3e1e1" />
                                 <Label Content="Navn:" Grid.Row="2" Grid.Column="1" HorizontalContentAlignment="Right" />
                                 <TextBox x:Name="TxtCategoryActiveName" Grid.Row="2" Grid.Column="2" Height="25" />
    
                                 <!--Row 3-->
                                 <Rectangle Grid.Row="3" Grid.Column="1" Fill="#d3d0d0" />
                                 <Rectangle Grid.Row="3" Grid.Column="2" Fill="#d3d0d0" />
                                 <Rectangle Grid.Row="3" Grid.Column="3" Fill="#d3d0d0" />
                                 <CheckBox x:Name="CbxCategoryActiveGlobal" Content="Global:" Grid.Row="3" Grid.Column="0" Margin="105,10,185,10" VerticalAlignment="Center"  HorizontalContentAlignment="Left" Grid.ColumnSpan="3" />
    
                                 <!--Row 4-->
                                 <Rectangle Grid.Row="4" Grid.Column="1" Fill="#e3e1e1" />
                                 <Rectangle Grid.Row="4" Grid.Column="2" Fill="#e3e1e1" />
                                 <Rectangle Grid.Row="4" Grid.Column="3" Fill="#e3e1e1" />
                                 <CheckBox x:Name="CbxCategoryActiveActive" Content="Aktiv:" Grid.Row="4" Grid.Column="0" Margin="105,10,185,10" VerticalAlignment="Center"  HorizontalContentAlignment="Left" Grid.ColumnSpan="3" />
    
                                 <!--Row 5-->
                                 <Button x:Name="BtnCategoryActiveSave" Content="Gem" Width="150" Grid.Column="1" Margin="0 5 0 0" Grid.Row="5" Grid.ColumnSpan="5" HorizontalAlignment="Center" HorizontalContentAlignment="Center" />
                             </Grid>
                         </StackPanel>
    
                     </Grid>
                 </Grid>
             </TabItem>
             <TabItem Header="Inaktive" Style="{StaticResource tabItemSmall}" >
             </TabItem>
         </TabControl>
     </Grid>
 </UserControl>
    
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Documents;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;
    
 namespace Views.Account
 {
     /// <summary>
     /// Interaction logic for AccountObsoleteView.xaml
     /// </summary>
     public partial class AccountObsoleteView : UserControl
     {
         public AccountObsoleteView()
         {
             InitializeComponent();
             DataContext = new ViewModel.Account.CategoryViewModel();
         }
     }
 }
windows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

cooldadtx avatar image
0 Votes"
cooldadtx answered Anja-7727 commented

In general for bindings you can use the Output window to see if a binding is failing. WPF generates messages for things like a bad binding.

If you are trying to debug why your binding doesn't have the right data then that should be handled inside the code that is setting up the property you're binding to. In your case it looks like whatever is setting your 'Categories_getActive' value.

In the rare cases you cannot simply debug the property that is being bound to then you can also create a dummy value converter and assign it to the control. Every value in the binding will go through the converter allowing you to see the values as you go by. This article describes that approach.

· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I maybe misunderstand you.

But I am not using try/catch primary for debugging the code, I use them (maybe that is wrong?) so when the end user gets an error, he can say - the message says ...... (and then the error message I have provided in the code). That way, if there is an error, I have a change to see when how and why.

But when binding in the UserControl is on the design page and not the code behind, I do not know how to make a try/catch and throw a specific error message?

When debugging I make a run to curser. But when saying the DB crash nothing happens in the wpf program nothing tells the user - there is an error with error message, so I don't know it is because the db crashes Or other errors that my happen.

It isn't on a control - that I know how to handle. It is only in the cases where I Binding to an ListView in design window I have problems to see how I can get to the error message to tell me what error an user would get.

Best regards
Simsen :-)

0 Votes 0 ·

For an end user, to me, there are only a couple of cases where they should see any errors. The first case is when you retrieve the data that ultimately becomes the source for your UI. You should be using a try-catch in the code behind and ideally logging to someplace like the event log or a custom log file. Your view model can expose a property that indicates the loading of the data failed and perhaps an error message if you want to bubble it to the user. This is the most common scenario.

Any binding-specific issues such as bad property names should be detected by you during debugging so you don't need those for the end user. However if you really want to get these as well then you can create a custom trace listener for the PresentationTraceSources which is what it writes to. I've never done that so I cannot answer to the behavior.


1 Vote 1 ·

Thank you very much.

I didn't have that thought logging to something. I will look into and send a message to the user from the view model.

Best regards
Simsen :-)

0 Votes 0 ·

Hi,

I just want to tell you, I really appreciate your help.

Tonight I have made an exception method that sends an email when exception occours. Tomorrow I will make a log file as well. So I'm using your suggestions.

Best regards
Simsen :-)

0 Votes 0 ·

Issues related to data conversion (such as the inability to convert a string to a date-time) may or may not show up to the end user. In these cases you might look into setting the Validation properties on the control. IIRC this then enables you to define an event handler in the codebehind that is called to allow you to capture the error and potentially show it to the user. I think this article may explain that approach better.

1 Vote 1 ·