Bonjour, dans une solution WPF j'ai un userControl qui contient une TextBox et un label, un Model qui implémente mes variables et une vue qui montre le résultat. Comme suit :
User control :
et son code :Code:
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 <UserControl x:Class="ControlsLibrary.CtrTextBox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ControlsLibrary" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="50" d:DesignWidth="400" mc:Ignorable="d"> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/Dictionaries;component/Styles/ControlsStyle.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> <Grid HorizontalAlignment="Right" DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CtrTextBox}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label Content="{Binding TextBoxEntitled}" /> <TextBox x:Name="TB" Grid.Column="1" Width="{Binding TextBoxWidth}" HorizontalAlignment="Right" VerticalContentAlignment="Center" CharacterCasing="{Binding TextBoxCharacterCasing}" GotFocus="TB_GotFocus" IsEnabled="{Binding TextBoxEnabledState}" MaxLength="{Binding TextBoxMaxLength}" MouseEnter="TB_MouseEnter" PreviewKeyDown="TB_PreviewKeyDown" Style="{StaticResource TextBoxStyle}" Text="{Binding TextBoxText}" TextWrapping="Wrap" /> </Grid> </UserControl>
le Model :Code:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace ControlsLibrary { /// <summary> /// Logique d'interaction pour CtrTextBox.xaml /// </summary> public partial class CtrTextBox : UserControl { public CtrTextBox() { InitializeComponent(); } public TextBox InternalTextBox { get => TB; } public static readonly DependencyProperty TextBoxTextProperty = DependencyProperty.Register("TextBoxText", typeof(string), typeof(CtrTextBox), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); public string TextBoxText { get => (string)GetValue(TextBoxTextProperty); set => SetValue(TextBoxTextProperty, value); } public static readonly DependencyProperty TextBoxEntitledProperty = DependencyProperty.Register("TextBoxEntitled", typeof(string), typeof(CtrTextBox), new PropertyMetadata(null)); public string TextBoxEntitled { get => (string)GetValue(TextBoxEntitledProperty); set => SetValue(TextBoxEntitledProperty, value); } public static readonly DependencyProperty TextBoxEnabledStateProperty = DependencyProperty.Register("TextBoxEnabledState", typeof(bool), typeof(CtrTextBox), new PropertyMetadata(true)); public bool TextBoxEnabledState { get => (bool)GetValue(TextBoxEnabledStateProperty); set => SetValue(TextBoxEnabledStateProperty, value); } public static readonly DependencyProperty TextBoxWidthProperty = DependencyProperty.Register("TextBoxWidth", typeof(double), typeof(CtrTextBox), new PropertyMetadata(new double())); public double TextBoxWidth { get => (double)GetValue(TextBoxWidthProperty); set => SetValue(TextBoxWidthProperty, value); } public static readonly DependencyProperty TextBoxCharacterChasingProperty = DependencyProperty.Register("TextBoxCharacterChasing", typeof(CharacterCasing), typeof(CtrTextBox), new PropertyMetadata(CharacterCasing.Normal)); public CharacterCasing TextBoxCharacterCasing { get => (CharacterCasing)GetValue(TextBoxCharacterChasingProperty); set => SetValue(TextBoxCharacterChasingProperty, value); } public static readonly DependencyProperty TextBoxMaxLengthProperty = DependencyProperty.Register("TextBoxMaxLength", typeof(int), typeof(CtrTextBox), new PropertyMetadata(new int())); public int TextBoxMaxLength { get => (int)GetValue(TextBoxMaxLengthProperty); set => SetValue(TextBoxMaxLengthProperty, value); } private void TB_GotFocus(object sender, RoutedEventArgs e) { ((TextBox)sender).SelectAll(); e.Handled = true; } private void TB_MouseEnter(object sender, MouseEventArgs e) { if (!string.IsNullOrEmpty(((TextBox)sender).Text)) { ((TextBox)sender).SelectAll(); e.Handled = true; } } private void TB_PreviewKeyDown(object sender, KeyEventArgs e) { TextBox currentTxtBox = sender as TextBox; if ((e.Key == Key.OemComma || e.Key == Key.OemPeriod || e.Key == Key.Decimal) && (currentTxtBox.Text.IndexOf(",") > -1 || currentTxtBox.Text.Length == 0)) { e.Handled = true; return; } if (e.Key == Key.Decimal) { e.Handled = true; int LastLocation = currentTxtBox.SelectionStart; currentTxtBox.Text = currentTxtBox.Text.Insert(LastLocation, ","); currentTxtBox.SelectionStart = LastLocation + 1; } } } }
avec le messageBox qui va servir a tester le changement de ma variableCode:
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 using System.ComponentModel; using System.Windows; namespace Email_Configuration.Models { public class TestModel : INotifyPropertyChanged { private string _testString; public string TestString { get => _testString; set { _testString = value; OnPropertyChanged(nameof(TestString)); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); MessageBox.Show($"Property changed : {propertyName}"); } } }
et la vue :
et son code :Code:
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 <Page x:Class="Email_Configuration.Views.TestPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:ControlsLibrary;assembly=ControlsLibrary" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Email_Configuration.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:model="clr-namespace:Email_Configuration.Models" Title="TestPage" d:DataContext="{d:DesignInstance Type=model:TestModel}" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <controls:CtrTextBox x:Name="TestUC" TextBoxText="{Binding TestString, UpdateSourceTrigger=PropertyChanged}" TextBoxWidth="100" /> </Grid> </Page>
Je n'ai aucune erreur de compilation mais le comportement de la TextBox est bizzare , en effet le messageBox qui affiche le changement de la variable ne s'affiche que lorsque je quitte la zone de saisie de la textbox alors que UpdateSourceTrigger est défini sur OnPropertyChanged...Code:
1
2
3
4
5
6
7
8
9 public partial class TestPage : Page { private TestModel _testModel = new TestModel(); public TestPage() { InitializeComponent(); DataContext = _testModel; } }
Je ne vois pas trop se qui cloche. Merci de votre aide