IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

WPF Textbox Text using MVVM ne fonctionne pas


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Février 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Février 2015
    Messages : 26
    Points : 36
    Points
    36
    Par défaut WPF Textbox Text using MVVM ne fonctionne pas
    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 :
    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
    <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>
    et son code :

    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
    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;
                }
            }
        }
    }
    le Model :

    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
    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}");
            }
        }
    }
    avec le messageBox qui va servir a tester le changement de ma variable

    et la vue :

    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
    <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>
    et son code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 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...

    Je ne vois pas trop se qui cloche. Merci de votre aide

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 265
    Points : 1 843
    Points
    1 843
    Par défaut
    Est-ce qu'il ne faudrait pas que ce soit implémenter au niveau du control user directement ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Février 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargé d'affaire

    Informations forums :
    Inscription : Février 2015
    Messages : 26
    Points : 36
    Points
    36
    Par défaut
    C'est a dire ?? j'utilise cette implémentation car comme tous bon UserControl il est réutilisé un peu de partout dans ma solution et pour des usages divers et variés

  4. #4
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 175
    Points : 25 116
    Points
    25 116
    Par défaut
    Text="{Binding TextBoxText}"

    là aussi il faut ajouter update source trigger à property changed sinon il ne renvoit pas dans le UC, qui ne renverra pas dans le VM

    tu peux aussi faire en sorte sur ton UC que les gens qui l'utilisent n'ai pas à préciser property changed en le mettant en comportement par défaut (enfin il faut quand même le mettre dans le xaml du UC)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Les liens hyper textes sur PWP ne fonctionnent pas
    Par symallee dans le forum Powerpoint
    Réponses: 2
    Dernier message: 03/11/2017, 11h59
  2. Réponses: 3
    Dernier message: 02/09/2016, 13h37
  3. [Débutant] TextBox Binding Mode TwoWay ne fonctionne pas si ValidationRule
    Par Mr Cogito dans le forum Windows Presentation Foundation
    Réponses: 0
    Dernier message: 04/08/2015, 10h38
  4. text align justify ne fonctionne pas
    Par ickyknox dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 01/12/2013, 14h40
  5. [CS5] Texte dynamique qui ne fonctionne pas avec tous les chiffres
    Par Shikam dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 10/12/2010, 07h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo