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

Windows Presentation Foundation Discussion :

Bindind propiété ViewModel vers DP du UserControl [Débutant]


Sujet :

Windows Presentation Foundation

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut Bindind propiété ViewModel vers DP du UserControl
    Bonjour a tous,

    Je suis débutant en WPF et suis confronté à un problème qui semble trivial mais pour lequel je n'ai pas trouvé de réponse sur le net.

    Voilà mon problème:
    je souhaite réaliser une toolbar qui se cache avec une animation lorsque l'on clique sur un bouton et qui réapparait lorsqu'on clique sur se même bouton.

    Voilà la manière dont je procède:

    j'ai un view-model qui implémente INotifyProperty qui propose une propriété"Visible".
    Cette propriétéest modifiée par une commande "VisibleChangedCmd" comme le montre le code qui suit:

    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
    	public class ccAutoHideToolBarViewModel : ViewModelBase
    	{
            private ccAutoHideToolBarModel m_model;
            private bool m_bVisible;
     
            public bool Visible
            {
                get { return m_bVisible; }
                set
                {
                    if (m_bVisible != value)
                    {
                        m_bVisible = value;
                        RaisePropertyChanged("Visible");
                    }
                }
            }
     
            private CommandImpl m_VisibleChangedCmd;
     
            public ICommand VisibleChangedCmd
            {
                get
                {
                    return m_VisibleChangedCmd;
                }
            }
     
    		public ccAutoHideToolBarViewModel()
    		{
                m_model = new ccAutoHideToolBarModel();
                m_VisibleChangedCmd = new CommandImpl(ExecuteVisibleChangedCmd, CanExecuteVisibleChangedCmd);   
    		}
     
            #region command
            public bool CanExecuteVisibleChangedCmd(object parameter)
            {
                return true;
            }
     
            public void ExecuteVisibleChangedCmd(object parameter)
            {
                Visible = !Visible;
            }
            #endregion
        }
    Ma propriété "Visible" est bien modifée sur commande donc pas de problème de ce coté là.

    J'ai maintenant une vue composée du fichier .xaml et du code behind associé.

    Dans mon code behind, je déclare une dependency property "IsExtended":

    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
    	public partial class ccAutoHideToolBar : UserControl
    	{
            public bool IsExtended
            {
                get { return (bool)this.GetValue(IsExtendedProperty); }
                set { this.SetValue(IsExtendedProperty, value); }
            }
            public static readonly DependencyProperty IsExtendedProperty = DependencyProperty.Register(
              "IsExtended", typeof(bool), typeof(ccAutoHideToolBar), new PropertyMetadata(false, OnIsExtendedChanged));
     
     
            public ccAutoHideToolBar()
    		{
    			this.InitializeComponent();
    			// Insert code required on object creation below this point.
    		}
     
            protected static void OnIsExtendedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ccAutoHideToolBar toolbar = (ccAutoHideToolBar)d;
                bool visible = (bool)e.NewValue;
     
                Storyboard animation;
                if(visible)
                    animation = (Storyboard)toolbar.Resources["appearToolBar"];
                else
                    animation = (Storyboard)toolbar.Resources["vanishToolBar"];
     
                animation.Begin();
            }
    	}
    Sur changement de cette DP "IsExtended", je lance un animation qui vient cacher ou faire apparaître ma tool bar fonction de sa valeur.

    Mon problème est le suivant, je ne parviens pas à faire le binding entre ma DP "IsExtended" de ma vue et ma propriété Visible de mon Vue-Model.
    Les seuls exemples que je rencontre traitent d'un binding entre une DP d'un objet composant ma vue et une propriété du model. (<TextBox Content={Binding TextVM}/> par exemple)

    Voilà mon .xaml:

    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
    <UserControl
    	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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    	mc:Ignorable="d"
    	xmlns:local="clr-namespace:WpfCustomControlLibraryV5"
        xmlns:vm="clr-namespace:WpfCustomControlLibraryV5.ViewModels"
    	x:Class="WpfCustomControlLibraryV5.ccAutoHideToolBar" x:Name="AutoHideToolBar"
    	d:DesignWidth="640" d:DesignHeight="480" RenderTransformOrigin="0.5,0.5">
     
        <UserControl.Resources>
            <vm:ccAutoHideToolBarViewModel x:Key="ccAutoHideToolBarViewModel"/>
            <Storyboard x:Key="appearToolBar">
            	<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="LayoutRoot">
            		<EasingDoubleKeyFrame KeyTime="0" Value="50"/>
            		<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
            	</DoubleAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="vanishToolBar">
            	<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="AutoHideToolBar">
            		<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            		<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="50"/>
            	</DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </UserControl.Resources>
        <UserControl.DataContext>
            <vm:ccAutoHideToolBarViewModel/>
        </UserControl.DataContext>
        <Grid x:Name="LayoutRoot">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="24"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="actionButton"  Grid.Column="0" VerticalAlignment="Center" Command="{Binding VisibleChangedCmd}" Background="Transparent" BorderBrush="Transparent" Focusable="False">Toolbox
                <Button.LayoutTransform>
                    <RotateTransform Angle="-90"></RotateTransform>
                </Button.LayoutTransform>
            </Button>
            <ToolBarPanel x:Name="toolBarPanel" Grid.Column="1" Width="50" VerticalAlignment="Center">
                <Button>Test1
                </Button>
                <Button>Test2
                </Button>
                <Button>Test3
                </Button>
                <Button>Test4
                </Button>
            </ToolBarPanel>
        </Grid>
    </UserControl>
    Merci d'avance pour ceux s'attarderont sur mon problème!

  2. #2
    Rédacteur/Modérateur
    Avatar de beekeep
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    2 005
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 2 005
    Points : 3 325
    Points
    3 325
    Par défaut
    Bonjour,

    pas besoin d'ajouter une DP dans la vue, la propriété du ViewModel suffit.
    Il faut juste binder la visibilité de la toolbar sur la propriété Visible.

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Bonsoir,
    Merci pour ta réponse.
    Quand tu dis
    binder la visibilité de la toolbar
    , de quelle propriété et de quelle classe parles tu précisément (UserControl.Visible ? )?
    Je passe par une DP pour pouvoir déclencher les animations qui vont décaler la toolbar hors de la fenêtre ou dans la fenêtre grace au callback de la DP.
    Je ne souhaite pas à proprement parler faire disparaître le contrôle.
    En gros, ma problématique c'est de déclencher un animation de ma vue sur un propertyChanged du view-model.
    Est ce que c'est bien ce tu as compris?

  4. #4
    Rédacteur/Modérateur
    Avatar de beekeep
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    2 005
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 2 005
    Points : 3 325
    Points
    3 325
    Par défaut
    oui j'ai un peu raccourcis mais c'est le même principe pour lancer des animations.

    Au lieu de binder directement la visibilité il faut appliquer un style qui lance les animations en fonction de la propriété du ViewModel:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <ToolBarPanel Style="{StaticResource VisibleElement}" ...
    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
    <Style x:Key="VisibleElement" TargetType="FrameworkElement">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Visible}" Value="True">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:1" />
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.25" Duration="0:0:1" />
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.ExitActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Bonjour beekeep,

    Merci pour ta réponse! J'ai testé et ça fonctionne!
    Je découvre avec ta réponse qu'un storyboard n'est pas forcément rattaché à un eventTrigger dans le code xaml, ce qui me rassure!
    J'ai une question qui reste en suspend...
    Dans mon code xaml, où et comment faire le binding de ma DP si j'avais persisté dans son utilisation.
    Je rappelle qu'il s'agissait de binder une propriété classique de mon view-model avec une DP de vue de mon UserControl déclarée dans le code behind.
    Merci de m'éclairer sur ce point STP.

  6. #6
    Rédacteur/Modérateur
    Avatar de beekeep
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    2 005
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 2 005
    Points : 3 325
    Points
    3 325
    Par défaut
    Un exemple d'utilisation d'une DP pour ton cas:

    1- Créer un composant (UserControl) spécifique pour la barre d'outils (MyToolBar) qui contient le ToolBarPanel

    2- Créer la DP IsExtended dans la classe MyToolBar

    3- Utiliser la DP dans le UserControl:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Property="{Binding IsExtended, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
    4- Utilisation du composant MyToolBar avec ou sans Binding:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <MyNS:MyToolBar IsExtended="True" />
    <MyNS:MyToolBar IsExtended="False" />
    <MyNS:MyToolBar IsExtended="{Binding Visible}" /> <!-- Ici la DP est bindée avec la propriété du VM -->

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Merci pour ta réponse.

    Les points 1, 2 et 4 me paraissent clairs mais je butte sur le point 3...
    Tu fais un binding sur sur une DP d'un autre UserControl composant ma toolBar?

    Voilà ce que voudrais faire:

    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
    <UserControl
    	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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    	mc:Ignorable="d"
    	xmlns:local="clr-namespace:WpfCustomControlLibraryV5"
        xmlns:vm="clr-namespace:WpfCustomControlLibraryV5.ViewModels"
    	x:Class="WpfCustomControlLibraryV5.ccAutoHideToolBar" x:Name="AutoHideToolBar"
    	d:DesignWidth="640" d:DesignHeight="480" RenderTransformOrigin="0.5,0.5" IsExtended="{Binding Visible}">
     
        <UserControl.Resources>
            <vm:ccAutoHideToolBarViewModel x:Key="ccAutoHideToolBarViewModel"/>
            <Storyboard x:Key="appearToolBar">
            	<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="LayoutRoot">
            		<EasingDoubleKeyFrame KeyTime="0" Value="50"/>
            		<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
            	</DoubleAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="vanishToolBar">
            	<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="AutoHideToolBar">
            		<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            		<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="50"/>
            	</DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </UserControl.Resources>
        <UserControl.DataContext>
            <vm:ccAutoHideToolBarViewModel/>
        </UserControl.DataContext>
        <Grid x:Name="LayoutRoot">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="24"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="actionButton"  Grid.Column="0" VerticalAlignment="Center" Command="{Binding VisibleChangedCmd}" Background="Transparent" BorderBrush="Transparent" Focusable="False">Toolbox
                <Button.LayoutTransform>
                    <RotateTransform Angle="-90"></RotateTransform>
                </Button.LayoutTransform>
            </Button>
            <ToolBarPanel x:Name="toolBarPanel" Grid.Column="1" Width="50" VerticalAlignment="Center">
                <Button>Test1
                </Button>
                <Button>Test2
                </Button>
                <Button>Test3
                </Button>
                <Button>Test4
                </Button>
            </ToolBarPanel>
        </Grid>
    </UserControl>
    IsExtended étant une DP déclarée dans le code behind de mon UserControl.

    Le problème est que la DP n'est vraisemblablement pas connue à cet endroit donc je me pose la question de où faire ce binding dans le xaml de mon UserControl? (Je parviens à le faire en passant par le code behind)

  8. #8
    Rédacteur/Modérateur
    Avatar de beekeep
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    2 005
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 2 005
    Points : 3 325
    Points
    3 325
    Par défaut
    Dans ton cas la propriété IsExtended n'est pas au bon endroit, elle ne représente rien pour ton interface principale.
    C'est une propriété de la toolbar, elle doit être déclarée dans un UserControl dédié à la toolbar.

    Le point 3 montre comment utiliser cette DP en interne dans le UserControl de la toolbar. (pas dans le UserControl principal)
    On accède à la DP en utilisant une "relative source" qui est le UserControl lui-même. (UserControl.IsExtended)

  9. #9
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    OK, je comprends mieux.
    Merci beaucoup pour le temps consacré à mon problème et tes réponses pertinentes.
    A une prochaine fois!

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

Discussions similaires

  1. [UserControl] Binding vers le parent
    Par al2000 dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 26/09/2011, 16h41
  2. Réponses: 4
    Dernier message: 30/06/2011, 18h55
  3. Passage de données d'une page vers un UserControl
    Par PatStan17 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 22/03/2011, 08h18
  4. [MVVM] Problème de binding, UserControl vers ViewModel
    Par Phil350 dans le forum Windows Presentation Foundation
    Réponses: 6
    Dernier message: 06/10/2010, 17h35
  5. Variables window vers usercontrol
    Par Anycee14 dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 18/07/2010, 19h24

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