2013-04-15 2 views
3

Я создал приложение WPF с привязкой некоторого текстового поля. Я использую ошибку проверки, чтобы проверить, соответствуют ли значения. Проверка проверяет базу данных, чтобы увидеть, имеются ли введенные данные.XamlParseException on ValidationError при запуске приложения

Если я вхожу ложное значение, моя ошибка проверки поймать ошибку whitout проблемы :)

Тем не менее, если я вхожу хорошее значение, и если я закрою приложение и перейти на моей базе данных удалить значение, когда я заново запускаю приложение, загружаются самые последние данные, и здесь ... У меня есть хороший Crash: «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"); 
     } 
    } 

Вот мой Validation 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

+0

Если ваше приложение выходит из строя, вы должны получить исключение. Было бы полезно также опубликовать его. – Jehof

+0

Я отредактировал мое сообщение: Исключение составляет XamlParseException с InnerException = {«TELOU не существует!»} Вместо отображения «TELOU не существует» в следующем текстовом поле (предупреждающая метка) исключение не выбрасывает. –

+0

Попробуйте следующее: (без кавычек) –

ответ

0

В качестве первой помощи, пожалуйста, подпишитесь на диспетчеру unhandle исключения (в идеале в App.xaml.cs)

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

Это поможет вам зарегистрировать информацию об аварии.

Попробуйте этот подход для templatising Validate включен Textbox

 <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

+0

Привет, я подписываюсь на диспетчера, но зачем мне писать в «App_DispatcherUnhandledException()»? Я использую ваш шаблон без изменений. Для ссылок codeProjects я их уже прочитал. –

+0

App.xaml - это точка входа для приложений WPF. Поэтому обработка необработанных исключений диспетчера в App.xaml.cs помогает вам не повторять все места. Вы можете сделать необходимую регистрацию и решить дальнейшие действия, как указано в статье MSDN. Что касается аварии, с которой вы сталкиваетесь, необработанный код Dispatcher поможет вам отлаживать визуальную студию, чтобы увидеть трассировку стека и получить основную причину вашей проблемы. Как назначить viewmodel вашему представлению? Вы написали его внутри конструктора xaml? – RockWorld

+0

У меня есть новости! Проблема возникает из-за наблюдаемого набора. Когда пользователь вводит данные, он вводится в TextBox, тогда проверка может отображать предупреждающую метку рядом с текстовым полем. Но, когда я загружаю данные, данные загружаются в наблюдаемый набор, поэтому мне нужно найти способ, чтобы не проверять данные, когда данные установлены из TextBox. У вас есть идея, пожалуйста? Спасибо. –

0

Возможно, вы столкнулись с крахом в конструкторе вашего класса, который определяет ваше поле m_strCodeIntervenant. Возможно, что-то использует ранее кэшированное «хорошее» значение и обходит проверку, устанавливая поле напрямую.

Установите точку останова и проанализируйте, что происходит.

+0

Ошибка, когда i, когда моя база данных задала значение m_strCodeIntervenant. –

+0

Вы не можете бросать исключения в конструктор, когда Xaml использует его. Помните, что Xaml - это просто язык сериализации объекта, и неспособность создать объект приведет к исключению XamlParseException (хотя это немного вводит в заблуждение). Проделайте некоторую проверку ошибок, если вы должны установить значение в конструкторе или предпочтительном рефакторе, чтобы вы не выполняли бизнес-логику в конструкторе. Создание объекта должно быть легким. – MrDosu

+0

, но почему у меня такая ошибка только при запуске приложения. Если все мои данные в порядке, запуск программы без проблем. Я вводил плохие данные, исключение исключения проверки исключений. –

0

XAML не отображает исключения, только на выходном окне.

ваш код выдает ошибку, но отображается только в окне вывода.

Когда исключение находится в начале элемента управления, он не может обрабатывать и удаляет приложение.

не бросайте исключение, обрабатывайте ошибку самостоятельно.

Смежные вопросы