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 :

Combobox : Highlighted ComboboxItem et Scrollviewer.


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de SetaSensei
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Par défaut Combobox : Highlighted ComboboxItem et Scrollviewer.
    Bonjour,

    J'ai eu un peu de mal à bien exprimer mon besoin dans le titre, désolé mais je n'ai rien trouvé de plus clair.

    Voici mon problème : j'ai une combobox (une radCombobox par telerik pour être plus exact) qui contient une liste relativement longue d'éléments (50 < x < 100).
    L'utilisateur peut taper la ou les premières lettres afin de se déplacer rapidement dans la sélection, mais le fait que le début de sélection soit en bas du panel le dérange.
    Du coup je voudrai "remonter" mon premier élément présélectionné en haut du fameux panel.

    J'ai remarqué qu'en laissant la touche appuyée, le déplacement que je recherche se fait tout seul, mais je n'ai pas trouvé le moyen de simuler ce comportement.

    Ma seconde solution est donc de manipuler la scrollbar. J'arrive à récupérer mes billes mais je ne maîtrise pas du tout la logique de placement des contrôles en WPF.
    Voici ce que j'ai commencé à 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
     
            private void cb_PreviewKeyUp(object sender, KeyEventArgs e)
            {
                if (sender != null)
                {
                    RadComboBox rd = (RadComboBox)sender;
                    if (rd != null) SelectHighlighted(rd);
                }
            }
     
            private void SelectHighlighted(RadComboBox rBox)
            {
                ItemContainerGenerator _iGenerator = rBox.ItemContainerGenerator;
                for (int i = 0; i < rBox.Items.Count; i++)
                {
                    DependencyObject _container = _iGenerator.ContainerFromIndex(i);
                    RadComboBoxItem rItem = _container as RadComboBoxItem;
     
                    if (rItem != null)
                    {
                        if (rItem.IsHighlighted)
                        {
                            // Je récupère le panel appartenant à ma combobox :
                            StackPanel _sPanel = _container.GetVisualParent<StackPanel>();
                            // Que mettre comme offset ?
                            _sPanel.ScrollOwner.ScrollToVerticalOffset(rItem ?);
                            return;
                        }
                    }
                }
            }
    Y a-t-il un moyen plus simple pour régler mon problème ?
    Si non, avez-vous une idée pour récupérer l'offset vertical de mon item au moment du keyup ?

    J'espère avoir été clair et merci de m'avoir lu et encore plus si vous pouviez me répondre.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 52
    Par défaut
    Salut, je ne sais pas si j'ai bien compris ta question mais peut-être que cet exemple avec une listbox pourrait t'aider.
    Cela recherche le ScrollViewer de la listbox pour apres se déplacer à l’élément souhaité. Contrairement à ScrollIntoView là l’élément sera positionné en haut.

    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
     private void button1_Click(object sender, RoutedEventArgs e)
            {
     
                ScrollViewer listBoxScrollViewer = FindChild<ScrollViewer>(listBox1);
                listBoxScrollViewer.ScrollToVerticalOffset(listBox1.SelectedIndex);
            }
     
            private static T FindChild<T>(DependencyObject reference) where T : class
            {
                var queue = new Queue<DependencyObject>();
                queue.Enqueue(reference);
                while (queue.Count > 0)
                {
                    DependencyObject child = queue.Dequeue();
                    T obj = child as T;
                    if (obj != null)
                    {
                        return obj;
                    }
     
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(child); i++)
                    {
                        queue.Enqueue(VisualTreeHelper.GetChild(child, i));
                    }
                }
                return null; 
            }

  3. #3
    Membre éclairé Avatar de SetaSensei
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Par défaut
    Bonjour,

    C'est peut être ça.
    Je suis sur un autre ticket actuellement, mais je vais tester ta solution dans la journée.

    Merci beaucoup pour la proposition en tout cas.

  4. #4
    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 SetaSensei.
    Helas l'exemple de la ListBox n'est pas applicable à la Combo car elle n'as pas de methode ScrollIntoView......
    Son control template est particulierement "mine" dirais-je....car il comporte à l'interieur un control winform WPF "clandestin" qui s'appelle TextBoxView que microsoft appelle pudiquement un "internal leightweight control" avec internal= inaccesible via l'API normale......
    D"ailleurs il n'existe aucune description de ce TextBoxView dans les modeles de controltemplate (aero,luna etc......) fournis pour tous les controls WPF...mis à part une reference sous forme de "part_ContentHost".....

    Je te suggere autant pour la fonctionnalite cherche (afficher en haut le premier element) la CollectionView du Combo avec filtre qui marche tout aussi bien que tu peux personnaliser à ton gre.......
    Code behind data :
    Code c# : 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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;
    using System.Collections.ObjectModel;
     
    namespace WpfComboBoxSuggest
    {
     
        public class MyItem : INotifyPropertyChanged
        {
            public MyItem()
            {
                this.FirstName = "";
                this.LastName = ""; 
            }
            public MyItem(string MyFirstName)
            {
                this.FirstName = MyFirstName; 
            }
            private string _FirstName;
            public string FirstName
            {
                get { return _FirstName; }
                set { _FirstName = value; OnPropertyChanged("FirstName"); }
            }
            private string _LastName;
            public string LastName
            {
                get { return _LastName; }
                set { _LastName = value; OnPropertyChanged("LastName"); }
            }
            #region INotifyPropertyChanged Membres
     
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propName));
     
                }
            }
            #endregion
        }
        public class MyListItem : ObservableCollection<MyItem>
        {
            public MyListItem()
            {
            }
        }
     
     }

    code-behind winform principal :
    Code c# : 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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Controls.Primitives;
    using System.ComponentModel;
    using System.Globalization;
     
    namespace WpfComboBoxSuggest
    {
        /// <summary>
        /// Logique d'interaction pour WindowComboBox.xaml
        /// </summary>
        public partial class WindowComboBox : Window
        {
     
            MyListItem listNames = new MyListItem();
            public WindowComboBox()
            {
                InitializeComponent();
     
                this.DataContext = listNames;
            }
     
     
            ICollectionView view;
            private void Cbo_KeyUp(object sender, KeyEventArgs e)
            {
                if (e.IsUp)
                {
     
                    view = CollectionViewSource.GetDefaultView(this.Cbo.Items);
                    view.Filter = null;
                    view.Filter = new Predicate<object>(Contains);
                }
     
            }
            // le simple filtre
            public bool Contains(object de)
            {
                MyItem  obj = de as  MyItem;
                //Return members whose obj have FirstName.StartsWith(prefix)
                string prefix= this.Cbo.Text ;
                prefix.Trim(); 
                if (obj.FirstName.StartsWith(prefix, true,System.Globalization.CultureInfo.CurrentCulture )) return true;
                return false;
            }
            // affiche le visualtree
            private void btnShowVisualTree_Click(object sender, RoutedEventArgs e)
            {
                WinVisualTreeViewDisplay treeDisplay = new WinVisualTreeViewDisplay();
                treeDisplay.ShowVisualTree(this);
                treeDisplay.Show();
     
            }
     
         }
    }
    code xaml du winform principal :
    Code xaml : 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
     
    <Window x:Class="WpfComboBoxSuggest.WindowComboBox"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfComboBoxSuggest"
            Title="ComboBox SearchSuggest" Height="300" Width="300">
     
        <DockPanel >
            <ComboBox
                DockPanel.Dock="Left" 
                x:Name="Cbo"
                Width="150"
                AlternationCount="4"
                IsTextSearchEnabled="True" 
                IsEditable="True"
                ScrollViewer.CanContentScroll="True"
                IsReadOnly="False"
                IsSynchronizedWithCurrentItem="True"
                SelectedValuePath="FirstName"
                DisplayMemberPath="FirstName"
                MaxDropDownHeight="150"
                StaysOpenOnEdit="True"
                IsDropDownOpen="True" 
                KeyUp="Cbo_KeyUp"
                ItemsSource="{Binding}">
                <ComboBox.ItemsPanel>
                    <ItemsPanelTemplate> 
                        <VirtualizingStackPanel 
                            VirtualizingStackPanel.IsVirtualizing="True">
                        </VirtualizingStackPanel>
                    </ItemsPanelTemplate>
                </ComboBox.ItemsPanel> 
            </ComboBox>
            <!--un listbox en parrallele qui permet de suivre le deroulement de la selection-->
            <ListBox 
                DockPanel.Dock="Right" 
                x:Name="testLB"
                Width="150"
                DisplayMemberPath="FirstName"
                IsSynchronizedWithCurrentItem="True"
                ItemsSource="{Binding}">
            </ListBox>
            <!--un bouton pour afficher le visualtree actuel--> 
            <Button 
                DockPanel.Dock="Bottom" 
                x:Name="btnShowVisualTree"
                Content="ShowVisualTree"
                Click="btnShowVisualTree_Click"
                HorizontalAlignment="Stretch">
            </Button>
        </DockPanel>
    </Window>
    code behind du form auxiliaire ( affiche le visualtree):
    Code c# : 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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
     
    namespace WpfComboBoxSuggest
    {
        /// <summary>
        /// Logique d'interaction pour WinVisualTreeViewDisplay.xaml
        /// </summary>
        public partial class WinVisualTreeViewDisplay : Window
        {
            public WinVisualTreeViewDisplay()
            {
                InitializeComponent();
            }
            public void ShowVisualTree(DependencyObject element  )
            {
                // Clear the tree.
                treeElements.Items.Clear();
     
                // Start processing elements, begin at the root.
                ProcessElement(element, null);
            }
     
            public void ProcessElement(DependencyObject element, TreeViewItem  previousItem )
            {
     
                // Create a TreeViewItem for the current element.
                TreeViewItem item = new  TreeViewItem();
                item.Header = element.GetType().Name;
                item.IsExpanded = true;
                // Check whether this item should be added to the root of the tree
                // (if it's the first item), or nested under another item.
                if( previousItem == null)
                { 
                    treeElements.Items.Add(item);
                }
                else
                {  
                    previousItem.Items.Add(item); 
     
                }
     
                //  Check if this element contains other elements.
     
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
    		    {
    			    /* Process each contained element recursively.*/
                ProcessElement(VisualTreeHelper.GetChild(element, i), item);
    		    }
     
            }
        }
    }
    code xaml du winform(affiche visualtree):

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <Window x:Class="WpfComboBoxSuggest.WinVisualTreeViewDisplay"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WinVisualTreeViewDisplay"
            Height="300" Width="300">
     
        <TreeView
            Name="treeElements" 
            Margin="10"></TreeView>
    </Window>

    bon code................

Discussions similaires

  1. Multi-selection dans une ComboBox ?
    Par Moloko dans le forum MFC
    Réponses: 5
    Dernier message: 07/07/2021, 17h26
  2. Initialisation d'une ComboBox en fonction des ComboBoxItem
    Par Tuttu dans le forum Windows Presentation Foundation
    Réponses: 8
    Dernier message: 17/05/2010, 23h11
  3. [VB6] [Interface] ComboBox à plusieurs colonnes
    Par mtl dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 30/03/2004, 17h35
  4. combobox et readonly
    Par Mac leod dans le forum C++Builder
    Réponses: 6
    Dernier message: 28/11/2002, 10h27
  5. combobox->text
    Par clovis dans le forum C++Builder
    Réponses: 18
    Dernier message: 21/06/2002, 15h43

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