应用程序启动时ValidationError上的XamlParseException

时间:2013-04-15 12:47:23

标签: c# wpf xaml data-binding validation

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

如果我输入false值,我的验证错误会捕获错误whitout问题:)

然而,如果我输入一个好的价值,如果我关闭我的应用程序,然后继续我的数据库删除该值,当我重新启动我的应用程序时,最新的数据被加载,这里......我有一个好的崩溃:“XamlParseException”。

此异常是因为我删除了数据中的值,并且当验证查找我的数据库时,找不到数据。

我不明白为什么我在发射时会发生碰撞,但不会发生。

以下是我的验证示例:

    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));
    }


}

此崩溃发生在生产“发布”或“调试模式”中。

异常是XamlParseException,其中InnerException = {“TELOU不存在!”} 不是在文本框(警告标签)旁边显示“TELOU不存在”,而是抛出异常。

有人有想法吗?

非常感谢:)

致以最诚挚的问候,

Nixeus

3 个答案:

答案 0 :(得分:0)

作为急救,请订阅调度员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

答案 1 :(得分:0)

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

在那里设置断点并分析正在发生的事情。

答案 2 :(得分:0)

XAML不会仅在输出窗口上显示异常。

您的代码抛出错误但仅显示在输出窗口中。

当异常出现在控件的init上时,它无法处理并烧毁应用程序。

不要自己抛出异常处理错误。