应用启动时ValidationError上的XamlParseException

本文关键字:上的 XamlParseException ValidationError 启动 应用 | 更新日期: 2023-09-27 18:09:29

我创建了一个绑定了一些文本框的WPF应用程序。我使用验证错误来检查值是否正确。验证将查找数据库以查看输入的数据是否存在。

如果我输入一个假值,我的验证错误捕获错误没有问题:)

然而,如果我输入一个好的值,如果我关闭我的应用程序,然后去我的数据库删除值,当我重新启动我的应用程序时,最新的数据被加载,这里…我有一个很好的崩溃:"XamlParseException"。

这个异常是因为我删除了data中的一个值,并且当验证查找我的DataBase时,没有找到该数据。

我不明白为什么我在启动时崩溃了,但之后没有。

下面是我验证的一个例子:

    private string m_strCodeIntervenant;
    public string strCodeIntervenant
    {
        get { return m_strCodeIntervenant; }
        set
        {
            m_strCodeIntervenant = value;
            if (m_strCodeIntervenant.Trim() != "")
            {
                if (m_objIntervenant.ReadIntervenantCodebyCode(m_strCodeIntervenant) != 0)
                {
                    throw new ApplicationException(m_strCodeIntervenant.Trim() + " don't exist !");
                }
                FirePropertyChangedEvent("strCodeIntervenant");
            }
            else
            {
                m_objIntervenant.strNom = "";
                m_objIntervenant.strIntervenant = "";
            }
            FirePropertyChangedEvent("objIntervenant.strNom");
        }
    }

这是我的验证XAML:

<TextBox Grid.Column="1" Name="TextBox_Intervenant" TabIndex="2" VerticalAlignment="Center" Height="20" >
    <TextBox.Text>
        <Binding Path="strCodeIntervenant" >
            <Binding.ValidationRules>
                <ExceptionValidationRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

---------
<Style TargetType="{x:Type TextBox}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel LastChildFill="True">
                    <TextBlock Margin="50,0,0,0" DockPanel.Dock="Right"
                    Foreground="Red"
                    FontSize="10pt"
                    Text="{Binding ElementName=MyAdorner,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                    </TextBlock>
                    <Border BorderBrush="Red" BorderThickness="1">
                        <AdornedElementPlaceholder Name="MyAdorner" />
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这是我的XAML.cs(为了更好的视图,稍微清理一下):

public partial class MainWindow : Window
{
    private void InitialiserControles()
    {
        TextBox_Description.Text = string.Empty;
        TextBox_EvtNum.Text = string.Empty;
        TimePicker_Heure.Value = null;
        TextBox_Intervenant.Text = string.Empty;
        TextBox_TypeEvenement.Text = string.Empty;
        TextBloc_Note.Text = string.Empty;
        DateTimePicker_Date.SelectedDate = DateTime.Today;
        DateTimePicker_Relance.SelectedDate = null ;
    }
    public ObservableCollection<Evenement> Collection_Evenements = new ObservableCollection<Evenement>();
    Evenement myEvenement = new Evenement();
    private void MettreAJourTableauEvenements()
    {
        Collection_Evenements = myEvenement.GetEvenementsForCliCode(App.obj_myClient.m_strCode);
        Collection_Evenements.CollectionChanged += Collection_Evenements_CollectionChanged;
        myDataGridEvenements.ItemsSource = Collection_Evenements;
    }
    public MainWindow()
    {
            InitializeComponent();
            this.DataContext = App.obj_myEvenement;
            //Load Evenement in DataGrid
            MettreAJourTableauEvenements();
    }

    private void myDataGridEvenements_SelectedCellsChanged_1(object sender, SelectedCellsChangedEventArgs e)
    {
        // Affiche le code évt sélectionné dans le tableau, dans les champs modifiable ( en haut de l'écran )
        var item = myDataGridEvenements.SelectedItem as Evenement;         
        if ((item != null))
        {
            App.obj_myEvenement.ReadEvenementebyNumero(item.strEvtNumero);
            TextBox_Description.Text = item.strDesignation;
            TextBox_EvtNum.Text = item.strEvtNumeroString;
            TextBox_Intervenant.Text = item.strCodeIntervenant;
            TextBox_TypeEvenement.Text = item.strEvtType;
            TextBloc_Note.Text = item.strNote;
            DateTimePicker_Date.SelectedDate = Evenement.ConvertToDateTimePicker(item.dDate);
            DateTimePicker_Relance.SelectedDate = Evenement.ConvertToDateTimePicker(item.dDateRelance);
            TimePicker_Heure.Value = item.dDate;
        }
    }
    private void Collection_Evenements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        {
            (e.OldItems[0] as Evenement).SupprimeEvenement();
            InitialiserControles();
        }
    }
    private void Window_Loaded_1(object sender, RoutedEventArgs e)
    {
        myDataGridEvenements.Focus();
        myDataGridEvenements.SelectedIndex = 0;
        myDataGridEvenements.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        Lbl_CliCodeCliDes.Content = App.obj_myClient.m_strCode.Trim() + " - " + App.obj_myClient.m_strNom.Trim();
        Lbl_CliCPostalVille.Content = App.obj_myClient.m_strCodePostal.Trim() + " - " + App.obj_myClient.m_strVille.Trim(); 
        App.obj_Parametres.LoadDataGridParams(myDataGridEvenements);
    }

    private bool IsValid(DependencyObject obj)
    {
        // return false;
        // The dependency object is valid if it has no errors, 
        //and all of its children (that are dependency objects) are error-free.
        return !Validation.GetHasError(obj)&&
        !LogicalTreeHelper.GetChildren(obj)
        .OfType<DependencyObject>()
        .Any(child => !IsValid(child));
    }

}

此崩溃发生在生产"发布"或"调试模式"。

异常是带有InnerException的XamlParseException = {"TELOU不存在!"}而不是在文本框(警告标签)旁边显示"TELOU don't exist",异常不会被抛出。

有人有什么想法吗?

谢谢你:)

最诚挚的问候,

Nixeus

应用启动时ValidationError上的XamlParseException

作为急救,请订阅dispatcher unhandle异常(理想情况下在App.xaml.cs中)

Msdn link - http://msdn.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx

这将帮助您记录崩溃信息。

尝试使用此方法模板化启用验证的文本框

        <Application.Resources>
  <ControlTemplate x:Key="TextBoxErrorTemplate">
    <DockPanel LastChildFill="True">
      <TextBlock DockPanel.Dock="Right" 
        Foreground="Orange" 
        FontSize="12pt">!!!!</TextBlock>
      <Border BorderBrush="Green" BorderThickness="1">
         <AdornedElementPlaceholder />
      </Border>
    </DockPanel>
  </ControlTemplate>
</Application.Resources>
<TextBox 
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"> 
[...]
<TextBox>

请参阅本文了解更多细节;http://www.codeproject.com/Articles/15239/Validation-in-Windows-Presentation-Foundation

您可能在定义m_strCodeIntervenant字段的类的构造函数中遇到崩溃。也许某些东西正在使用先前缓存的"good"值,并通过直接设置字段来绕过验证。

设置一个断点并分析发生了什么

XAML不显示异常,只在输出窗口显示。

你的代码抛出错误,但只显示在输出窗口。

当异常在控件的init上时,它无法处理并吹灭应用程序。