Bonjour

Je travaille sous WPF et je veux utiliser une ListBox avec un DataTemplate et ObservableCollection
j'utilise le Binding en mode "TwoWay" entre le texte d'une TextBox et une donnée de la ObservableCollection
j'utilise ValidationRule pour vérifier la validité du texte saisi
si je modifie le texte dans la TextBox tout est Ok
mais si le texte saisi comporte une erreur (dans mon exemple une chaîne vide) signalé par ValidationRule
le texte (une chaîne à blanc) n'est par transmis dans ma ObservableCollection , or j'aimerai pouvoir le faire (pour des raisons propres à mon application par exemple la sauvegarde de la ObservableCollection dans un fichier)
Pouvez-vous m'aider? Merci d'avance

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Xaml :

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local1="clr-namespace:WpfApplication1"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <DataTemplate x:Key="DataTemplate1">
            <TextBox x:Name="TextBox1" Width="100">
                <TextBox.Text>
                    <Binding Path="Texte1" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local1:NotEmptyValidationRule ValidatesOnTargetUpdated="True" Message="Le texte est obligatoire."/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
        </DataTemplate>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel LastChildFill="true">
                            <TextBlock DockPanel.Dock="Right" Margin="5,0,0,0" Text="?" TextAlignment="Center" VerticalAlignment="Center"
                                Width="20"
                                Background="Orange"
                                ToolTip="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}">
                            </TextBlock >
                            <Border BorderBrush="Red" BorderThickness="3">
                                <AdornedElementPlaceholder Name="MyAdorner" />
                            </Border>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <DockPanel>
        <Button DockPanel.Dock="Top" Content="Listing" Height="23" HorizontalAlignment="Left" Name="Listing1" VerticalAlignment="Center"
                        Width="75" Margin="150,0,0,0" Click="Listing1_Click"/>
        <ListBox x:Name="ListBox1" ItemTemplate="{StaticResource DataTemplate1}" ItemsSource="{Binding}" HorizontalAlignment="Left" Width="500"/>
    </DockPanel>
</Window>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Code MainWindow.xaml.cs :

    public partial class MainWindow : Window
    {
        ObservableCollection<classInfos> OCInfos;

        public MainWindow()
        {
            InitializeComponent();

            OCInfos = new ObservableCollection<classInfos>();

            classInfos classInfos1 = new classInfos();
            classInfos1.Texte1 = "Texte1";
            OCInfos.Add(classInfos1);

            classInfos classInfos2 = new classInfos();
            classInfos2.Texte1 = "Texte2";
            OCInfos.Add(classInfos2);

            DataContext = OCInfos;
        }

        private void Listing1_Click(object sender, RoutedEventArgs e)
        {
            int nCount = OCInfos.Count;

            for (int Ind1 = 0; Ind1 < nCount; Ind1++)
            {
                Console.WriteLine("");
                Console.WriteLine(OCInfos[Ind1].Texte1);
            }
        }
    }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Code INotifyPropertyChanged et ValidationRule :

    public class classInfos : INotifyPropertyChanged
    {
        private string _Texte1;
        public string Texte1
        {
            get { return _Texte1; }
            set
            {
                if (_Texte1 != value)
                {
                    _Texte1 = value;
                    OnPropertyChanged("Texte1");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class NotEmptyValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            string str = value as string;
            if (str != null)
            {
                if (str.Length > 0)
                    return ValidationResult.ValidResult;
            }
            return new ValidationResult(false, Message);
        }

        public String Message { get; set; }
    }