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 :

Modifier les propriétés d'un élément dans un template [Débutant]


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut Modifier les propriétés d'un élément dans un template
    Bonjour,

    J'ai une ListBox avec dedans un certains nombre d'éléments (dont un TextBlock) que j'ai mis en forme via un template.
    Ce que j'aimerai, c'est que sur un double clic sur mon ListBoxItem, je puisse éditer mon TextBlock (et il redevient non éditable à la perte du focus, mais ça). Et quand le TextBlock perd le focus, le tout repasse en "lecture seule".

    Vu que je n'ai pas trouvé de moyen "symple", de gérer les évènements sur des ListBoxItems, j'ai rajouté des handlers :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                EventManager.RegisterClassHandler(typeof(ListBoxItem), ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(lbiLeftButtonDownHandler));
                EventManager.RegisterClassHandler(typeof(ListBoxItem), ListBoxItem.MouseLeftButtonUpEvent, new RoutedEventHandler(lbiLeftButtonUpHandler));
                EventManager.RegisterClassHandler(typeof(ListBoxItem), ListBoxItem.MouseLeaveEvent, new RoutedEventHandler(lbiLeaveEventHandler));
                EventManager.RegisterClassHandler(typeof(ListBoxItem), ListBoxItem.MouseDoubleClickEvent, new RoutedEventHandler(lbiDoubleClickEventHandler));

    Et sur le doubleclic, que je récupère bien, j'aimerai rendre mon textblock éditable (a la rigueur, le cacher et afficher un textbox à la place, ca m'irait aussi). Mais le problème, c'est que je n'arrive pas à acceder a mon TextBox "tbListCardText".

    Le code du template :
    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
     
            <DataTemplate 
                x:Key="CardTemplate"
                DataType="{x:Type local:Card}">
                <Border Background="Transparent"
    					BorderBrush="DarkGray"
    					BorderThickness="0,0,0,0"
    					Padding="2">
                    <!-- Contenu d'une carte -->
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="10" Name="cardKeywordColumn" />
                            <ColumnDefinition Width="10" />
                            <ColumnDefinition Width="50*" />
                        </Grid.ColumnDefinitions>
                        <Rectangle Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Name="rectLabel" Stroke="{x:Null}" Width="10" Height="{Binding MainWindow.cardHeight}" Fill="{Binding colorText}" />
                        <Rectangle Grid.Column="1" HorizontalAlignment="Left" Stroke="{x:Null}" Width="9" Fill="#00000000" />
                        <TextBlock Grid.Column="2" Name="tbListCardText" Text="{Binding text}" Background="{Binding colorText}" />
                        <Rectangle Grid.Column="2" HorizontalAlignment="Right" Width="2" Margin="4" Name="rectangle2" Stroke="Black" Fill="Black" FlowDirection="RightToLeft" />
                    </Grid>
                </Border>
            </DataTemplate>
    Le code de la fonction appelée quand je fait un doubleclick :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            private void lbiDoubleClickEventHandler(object sender, RoutedEventArgs e)
            {
                ListBoxItem item = (ListBoxItem)sender;
                if (item.Content is Card)
                {
                    //MessageBox.Show("DoubleClick !");
                    Card currentCard = (Card)item.Content;
                    //tentative qui ne fonctionne pas :
                    //TextBlock tb = (TextBlock)item.Template.FindName("tbListCardText", item);
                    //tb.Visibility = false; = "AAAAAAAAAAAAAAAAAAAAAAAA";
                }
            }
    Donc, comment faire pour accéder à mon élément ?
    Merci d'avance ! (et s'il existe une méthode moins... crade ? pour acceder aux events des ListBoxItems, je prends aussi...).

    Merci d'avance !

  2. #2
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour Rakken..
    Parce que la presomption de bindabilite est notre credo fondamental....eh bien utilisons le binding....
    La tu es sur la piste en disant "cacher moi ce textblock" que je ne saurais voir grace à sa prop Visibility.
    Le TexbBock etant dans un DataTemplate le seul moyen d'y avoir acces c'est un style approprie comme suit:
    -Lorsque son ancestor ListBoxItem est dans l'etat "IsSelected=true" il change sa Visibilty(default True) à false .....et s'eclipse...

    Mais comment concilier Visibilty(enum) et IsSelected(boolean)...
    Maitre-jacques converter BoolToVisibilityConverter.cs y pourvoira à l'accoutume.....

    C'est presque termine il manque dans le DataTemplate le TextBox assis gentiment à cote du TexBlock .Un style identique à celui du textblock est necessaire.....
    -Lorsque son ancestor ListBoxItem est dans l'etat "IsSelected=true" il change sa Visibilty(default False) à True .....et surgit...

    Maitre binding s'occupe de mettre à jour -dans les coulisses- les valeurs de la collection avec un class Card outille avec son INotifyPropertyChanged....
    Et voila c'est fait...............
    code behind .cs du class test Card...
    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;
    using System.Collections.ObjectModel;
    using System.Windows.Media;
    namespace WpfListBoxItemEvent
    {
        public class Card:INotifyPropertyChanged
        {
            public Card(string t)
            {
                text = t;
     
            }
            private string m_text;
            public string text 
            {
                get { return m_text; }
                set
                {
                    m_text=value ; OnPropertyChanged("text");
                }
            }
     
     
     
            #region INotifyPropertyChanged Membres
     
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propName));
     
                }
     
            }
            #endregion
        }
        public class Cards:ObservableCollection<Card>
        {
            public Cards() 
            {
                for (int i = 0; i < 9; i++)
                {
                    ;
                    this.Add(new Card("item"+i.ToString()));
     
                }
     
            }
     
        }
    }
    code behind .cs du class BoolToVisibilityConverter...
    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Data;
     
    namespace WpfListBoxItemEvent
    {
        public class BoolToVisibilityConverter : IValueConverter
        {
            public object Convert(object value, Type targetType,
              object parameter, System.Globalization.CultureInfo culture)
            {
                bool param = bool.Parse(parameter as string);
                bool val = (bool)value;
     
                return val == param ? Visibility.Visible : Visibility.Hidden;
            }
     
            public object ConvertBack(object value, Type targetType,
              object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
     
    }
    code xam du winform (zero code behind applicatif):
    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
     
    <Window x:Class="WpfListBoxItemEvent.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfListBoxItemEvent"
            Title="MainWindow" Height="350" Width="525">
     
        <Window.Resources>
            <local:Cards x:Key="myDataSource"></local:Cards>
            <local:BoolToVisibilityConverter x:Key="boolToVis" />
     
            <Style 
                x:Key="GridBlockStyle"
                TargetType="{x:Type TextBlock}"   >
                <Setter Property="VerticalAlignment" Value="Center" />
                <Setter Property="Visibility" 
                        Value="{Binding Path=IsSelected, 
                        RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type ListBoxItem}},
                        Converter={StaticResource boolToVis}, 
                        ConverterParameter=False}" />
            </Style>
     
            <Style 
                x:Key="GridEditStyle"
                TargetType="{x:Type FrameworkElement}" >
                <Setter Property="VerticalAlignment" Value="Center" />
                <Setter Property="Visibility" 
                        Value="{Binding Path=IsSelected, 
                        RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type ListBoxItem}},
                        Converter={StaticResource boolToVis}, 
                        ConverterParameter=True}" />
            </Style>
            <DataTemplate 
                x:Key="CardTemplate"
                DataType="{x:Type local:Card}">
                <Border Background="Transparent"
    					BorderBrush="DarkGray"
    					BorderThickness="0,0,0,0"
    					Padding="2">
                    <!-- Contenu d'une carte -->
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="50*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" 
                                   Name="tbListCardText" 
                                   Text="{Binding text}"
                                   Background="LightBlue" 
                                   Style="{StaticResource GridBlockStyle}">
                        </TextBlock>
                        <TextBox Grid.Column="0" 
                                   Name="tbSosieListCardText" 
                                   Text="{Binding text}"
                                   FontSize="16"
                                   Background="White"
                                   Foreground="Red" 
                                   Style="{StaticResource GridEditStyle}">
                        </TextBox>
                    </Grid>
                </Border>
            </DataTemplate> 
        </Window.Resources>
        <StackPanel>
            <ListBox
                ItemTemplate="{StaticResource CardTemplate}"
                ItemsSource="{StaticResource myDataSource}">
            </ListBox>
        </StackPanel>
    </Window>
    bon code et bonne soiree.............

  3. #3
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Merci beaucoup !

  4. #4
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Merci encore pour ton code, il est super clair et m'a appris quelques notions dont j'ignorais l'existence.

    Par contre, tu te base sur le fait d'une case est sélectionnée ou pas, ce qui ne me convient pas (notamment dans la mesure ou je peux avoir de la multiselection pour derrière faire du drag & drop de masse), il me faudrait la même chose, mais activé au double clic.

    Le pb, c'est que comme tu te bases sur une propriété existante pour faire le switch entre textBox et textBloc (le fait qu'une carte soit sélectionnée), je ne sais pas tellement comment adapter le code pour que ce switch se fasse au double clic.
    Une idée ?

    Merci d'avance encore ;-))

  5. #5
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    Rebonjour Rakken...
    La c'est un besoin bien cible sur un bouton ....
    Un control bouton peut etre dans le DataTemplate mais le hic c'est qu'il ne dispose que de la prop IsPressed (une fausse prop car elle n'est disponible que dans les triggers)....et bascule immediatement de true à false des qu'on relache l'appui sur le bouton
    Alors qu'il nous faut une prop d'etat persistant du genre ToggleButton...qui bascule à la demande mais comment cacher les cases CheckBoxes.....
    Eh bien c'est ToggleButton -cousin du button- deguise en Button (grace à l'aide d'un TextBock en apparence seulement c'est un deguisement) mais qui conserve ses fonctionnalites entre autre la prop qui nous interesse IsChecked...

    voici le code
    -le class cards.cs deja vu
    -le converter BoolToVis deja vu
    -un ToggleButton cheval de troie inserer dans le datatemplate
    -plus besoin des styles:

    code xaml du winform(pas de code behind) :
    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
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    <Window x:Class="WpfListBoxItemEvent.ListBoxSwitchItem"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfListBoxItemEvent"
            Title="SwitchItem With ToggleButton" Height="300" Width="300">
        <Window.Resources>
            <local:Cards x:Key="myDataSource"></local:Cards>
            <local:BoolToVisibilityConverter x:Key="boolToVis" />
     
            <!-- Fill Brushes -->
     
            <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
                <GradientBrush.GradientStops>
                    <GradientStopCollection>
                        <GradientStop Color="#FFF" Offset="0.0"/>
                        <GradientStop Color="#CCC" Offset="1.0"/>
                    </GradientStopCollection>
                </GradientBrush.GradientStops>
            </LinearGradientBrush>
            <!-- Border Brushes -->
     
            <LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1">
                <GradientBrush.GradientStops>
                    <GradientStopCollection>
                        <GradientStop Color="#CCC" Offset="0.0"/>
                        <GradientStop Color="#444" Offset="1.0"/>
                    </GradientStopCollection>
                </GradientBrush.GradientStops>
            </LinearGradientBrush>
            <DataTemplate 
                x:Key="CardTemplate"
                DataType="{x:Type local:Card}">
                <Border Background="Transparent"
    					BorderBrush="DarkGray"
    					BorderThickness="0,0,0,0"
    					Padding="2">
                    <StackPanel 
                        Orientation="Horizontal" >
                        <!-- Contenu d'une carte -->
                        <Grid
                            Margin="5">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="50*" />
                            </Grid.ColumnDefinitions>
                            <TextBlock 
                                Grid.Column="0" 
                                Name="TextBlockCard" 
                                Text="{Binding text}"
                                FontSize="16"
                                Background="LightBlue"
                                Visibility="{Binding ElementName=ToggleEditMode,
                                            Path=IsChecked,
                                            Converter={StaticResource boolToVis},ConverterParameter=False }">
                            </TextBlock>
                            <TextBox 
                                Grid.Column="0" 
                                Name="TextBockCard" 
                                Text="{Binding text}"
                                FontSize="16"
                                Background="Black"
                                Foreground="Red"
                                Visibility="{Binding ElementName=ToggleEditMode,
                                            Path=IsChecked,
                                            Converter={StaticResource boolToVis},ConverterParameter=True}">
                            </TextBox>
                        </Grid>
                        <!--toggle button deguise en bouton-->
                        <ToggleButton 
                            x:Name ="ToggleEditMode"
                            HorizontalAlignment="Center"
                            HorizontalContentAlignment="Center"
                            VerticalAlignment="Center"
                            VerticalContentAlignment="Center"
                            IsChecked="False" >
                            <ToggleButton.Template>
                                <ControlTemplate 
                                    TargetType="ToggleButton">
                                    <Border
                                        BorderThickness="1"
                                        BorderBrush="{StaticResource NormalBorderBrush}" 
                                        CornerRadius="2"
                                        Padding="5"
                                        Background="{StaticResource NormalBrush}" >
                                        <TextBlock 
                                            HorizontalAlignment="Center"
                                            VerticalAlignment="Center"
                                            Text ="ClickEdit">
                                        </TextBlock >
                                    </Border>
                                </ControlTemplate>
                            </ToggleButton.Template>
                        </ToggleButton>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </Window.Resources>
        <StackPanel>
            <ListBox
                Height="200"
                ItemTemplate="{StaticResource CardTemplate}"
                ItemsSource="{StaticResource myDataSource}">
            </ListBox>
     
        </StackPanel>
    </Window>
    en esperant que cela reponde au souci..............
    bon code...

  6. #6
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Humm, oui, j'ai compris l'idée. Avec ça, je devrai pouvoir m'en sortir, merci beaucoup !

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

Discussions similaires

  1. Modifier les propriétés dans Word
    Par thyshimrod dans le forum Général Java
    Réponses: 0
    Dernier message: 11/03/2010, 16h52
  2. Réponses: 3
    Dernier message: 11/01/2006, 12h01
  3. Modifier les propriétés d'un fichier
    Par manu1407 dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 09/11/2005, 10h39
  4. [VBA-E]modifier les attributs d'un commentaire dans une cellule
    Par Olivier vb dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 15/03/2004, 10h26
  5. [EXCEL]Modifier les marges d'une page dans Excel
    Par ms91fr dans le forum Composants VCL
    Réponses: 4
    Dernier message: 06/01/2004, 15h26

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