3

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

如果我输入一个错误值,我的验证错误会捕获错误 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));
    }


}

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

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

有人有什么想法吗?

非常感谢 :)

此致,

尼克修斯

4

3 回答 3

0

作为急救,请订阅调度程序取消处理异常(最好在 App.xaml.cs 中)

Msdn 链接 - 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

于 2013-04-17T13:57:06.333 回答
0

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

在那里设置断点并分析发生了什么。

于 2013-04-17T14:31:15.767 回答
0

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

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

当异常发生在控件的初始化时,它无法处理并破坏应用程序。

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

于 2013-04-23T16:03:09.600 回答