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/Avalonia : Selection par lasso [Débutant]


Sujet :

C#

  1. #1
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut WPF/Avalonia : Selection par lasso
    Bonjour à tous,

    Je débute sur avalonia et wpf et je rencontre un problème avec le listbox. En effet, la sélection par lasso n'est pas implémentée de base sur le contrôle. Je m'attache donc à la tache pour la créer. J'ai essayé avec un adornerlayer mais le canvas utilisé pour le dessin masque les items. Je suis donc partis sur un behavior afin d'étendre le control listbox. Ca marche comme plus ou moins comme je veux. Le problème vient que le début de la zone de selection ne suit pas le scroll de la listbox et donc perd les items selectionnés lors du scroll.

    Comment puis je faire un behavior qui dessine bien sur le canvas et garde la position initiale pour avoir une sélection complète même après avoir scrollé? En gros il faudrait que le canvas scroll comme la listbox et mette à jour le point de départ.

    Ou alors je me plante complètement dans l'approche et il faut faire autrement. La question est donc comment?

    Merci pour l'aide et les éclaircissements.

    Le code 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
     
            <!-- DIRECTORY CONTENT -->
            <Grid Grid.Row="2">
     
                <Canvas x:Name="SelectionCanvas" Grid.Row="2"
                    IsHitTestVisible="False"
                    Margin="5" Panel.ZIndex="10"
                    Width="{Binding Width, ElementName=listBox}"
                    Height="{Binding Height, ElementName=listBox}"/>
     
                <ListBox x:Name="listBox"
                    ItemsSource="{Binding FiltredContent}"
                    SelectionMode="Multiple"
                    SelectedItems="{Binding SelectedItems}"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                    Margin="5" >
     
                    <interactivity:Interaction.Behaviors>
                        <behaviors:TestBehavior/>
                    </interactivity:Interaction.Behaviors>
     
                    <ItemsControl.Styles>
                        <Style Selector="ContentPresenter"  x:DataType="vm:DirContentItemViewModel">
                            <Setter Property="Margin" Value="10"/>
                        </Style>
                    </ItemsControl.Styles>
     
                    <ListBox.ItemsPanel >
                        <ItemsPanelTemplate >
                            <WrapPanel Orientation="Horizontal" />
                            <!-- https://stackoverflow.com/questions/4656717/how-to-set-margin-for-inner-controls-of-wrappanel -->
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
     
                </ListBox>
     
                <TextBlock Text="Pas de fichier à afficher"
                    IsVisible="{Binding EmptyContent}"
                    Foreground="Red"
                    HorizontalAlignment="Center" VerticalAlignment="Center"
                    FontSize="15"/>
     
            </Grid>
            <!-- END DIRECTORY CONTENT -->
    Et le code du behavior :
    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
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    public class TestBehavior : Behavior<ListBox>
        {
            enum SelectionMode
            {
                None,
                New,
                Add,
                Multi
            }
     
            ListBox? listBox;
            Canvas? _canvas;
            readonly Border _selectionRectangle = new()
            {
                BorderBrush = Brushes.Blue,
                BorderThickness = new Thickness(1),
                Background = new SolidColorBrush(Colors.LightBlue, 0.3),
                IsHitTestVisible = false,
                IsVisible = false
            };
            SelectionMode _mode = SelectionMode.None;
            bool _isSelecting;
            Point _startPoint;
            HashSet<object> _initialSelection = new();
            HashSet<object> newSelection = new();
     
            protected override void OnAttached()
            {
                base.OnAttached();
                if (AssociatedObject is not ListBox) throw new ArgumentException("AssociatedObject is null or is not Type of Listbox");
                listBox = AssociatedObject;
                listBox.PointerPressed += OnPointerPressedEvent;
                listBox.PointerMoved += OnPointerMoved;
                listBox.PointerReleased += OnPointerReleased;
     
                var scrollViewer = listBox.FindAncestorOfType<ScrollViewer>();
                if (scrollViewer != null)
                {
                    scrollViewer.ScrollChanged += OnScrollChanged;
                }
     
                Grid? ct = listBox.Parent as Grid ?? throw new ArgumentException("AssociatedObject is not in a Grid");
                _canvas = ct.Children[0] as Canvas ?? throw new ArgumentException("AssociatedObject has not a canvas");
                _canvas.Children.Add(_selectionRectangle);
            }
     
            protected override void OnDetaching()
            {
                if (_canvas is not null) _canvas = null;
                if (listBox is not null)
                {
                    var scrollViewer = listBox.FindAncestorOfType<ScrollViewer>();
                    if (scrollViewer != null)
                    {
                        scrollViewer.ScrollChanged -= OnScrollChanged;
                    }
     
                    listBox.PointerPressed -= OnPointerPressedEvent;
                    listBox.PointerMoved -= OnPointerMoved;
                    listBox.PointerReleased -= OnPointerReleased;
                }
                base.OnDetaching();
            }
     
            void OnScrollChanged(object? sender, ScrollChangedEventArgs e)
            {
                if (_canvas is null || listBox is null) return;
     
                var scrollViewer = sender as ScrollViewer;
                if (scrollViewer is null) return;
     
                var offsetY = scrollViewer.Offset.Y;
     
                // Mise à jour de la position du rectangle de sélection
                var currentTop = Canvas.GetTop(_selectionRectangle);
                Canvas.SetTop(_selectionRectangle, _startPoint.Y - offsetY);
            }
     
            void OnPointerPressedEvent(object? sender, PointerPressedEventArgs e)
            {
                if (!e.GetCurrentPoint(listBox).Properties.IsLeftButtonPressed) return;
                if (listBox is null || _canvas is null) return;
                SetMode(e.KeyModifiers);
                _startPoint = e.GetPosition(_canvas);
                _selectionRectangle.Width = 0;
                _selectionRectangle.Height = 0;
                Canvas.SetLeft(_selectionRectangle, _startPoint.X);
                Canvas.SetTop(_selectionRectangle, _startPoint.Y);
            }
     
            void OnPointerMoved(object? sender, PointerEventArgs e)
            {
                if (!_isSelecting || listBox is null || _canvas is null) return;
                if (!e.GetCurrentPoint(listBox).Properties.IsLeftButtonPressed) return;
                var pointerPosition = e.GetPosition(listBox);
                _selectionRectangle.IsVisible = true;
                var endPoint = e.GetPosition(_canvas);
                double x = Math.Min(_startPoint.X, endPoint.X);
                double y = Math.Min(_startPoint.Y, endPoint.Y);
                double width = Math.Abs(endPoint.X - _startPoint.X);
                double height = Math.Abs(endPoint.Y - _startPoint.Y);
                Canvas.SetLeft(_selectionRectangle, x);
                Canvas.SetTop(_selectionRectangle, y);
                _selectionRectangle.Width = width;
                _selectionRectangle.Height = height;
                SelectItems(listBox, new Rect(x, y, width, height));
            }
     
            void OnPointerReleased(object? sender, PointerReleasedEventArgs e)
            {
                _isSelecting = false;
                _selectionRectangle.IsVisible = false;
                _initialSelection.Clear();
                newSelection.Clear();
            }
     
            void SetMode(KeyModifiers key)
            {
                _isSelecting = true;
                if (key.HasFlag(KeyModifiers.Control))
                {
                    _mode = SelectionMode.Multi;
                }
                else if (key.HasFlag(KeyModifiers.Shift))
                {
                    _mode = SelectionMode.Add;
                }
                else
                {
                    _mode = SelectionMode.New;
                    listBox?.SelectedItems?.Clear();
                }
            }
     
            private void SelectItems(ListBox listBox, Rect selectionBounds)
            {
                if (listBox is null || _canvas is null) return;
     
                var scrollViewer = listBox.FindAncestorOfType<ScrollViewer>();
                var scrollOffset = scrollViewer?.Offset.Y ?? 0;
     
                foreach (var item in listBox.Items)
                {
                    var container = listBox.ContainerFromItem(item) as Control;
                    if (container == null) continue;
     
                    var itemBounds = new Rect(container.TranslatePoint(new Point(0, 0), _canvas) ?? new Point(), container.Bounds.Size);
                    itemBounds = new Rect(itemBounds.X, itemBounds.Y - scrollOffset, itemBounds.Width, itemBounds.Height);
     
                    bool isInside = selectionBounds.Intersects(itemBounds);
                    switch (_mode)
                    {
                        case SelectionMode.New:
                            if (isInside)
                            {
                                if (!listBox.SelectedItems.Contains(item))
                                {
                                    listBox.SelectedItems.Add(item);
                                }
                            }
                            else
                            {
                                if (listBox.SelectedItems.Contains(item))
                                {
                                    listBox.SelectedItems.Remove(item);
                                }
                            }
                            break;
                        case SelectionMode.Add:
                            if (isInside && !listBox.SelectedItems.Contains(item))
                            {
                                listBox.SelectedItems.Add(item);
                            }
                            break;
                        case SelectionMode.Multi:
                            if (isInside)
                            {
                                if (listBox.SelectedItems.Contains(item))
                                {
                                    listBox.SelectedItems.Remove(item);
                                }
                                else
                                {
                                    listBox.SelectedItems.Add(item);
                                }
                            }
                            break;
                    }
                }
            }
        }

  2. #2
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut
    Bon je me répond à moi-même et pour ceux qui passeraient.

    Le code initial gérait mal le scroll car il se faisait sur la listbox qui avait une hauteur supérieure à e qui etait visible. J'ai donc adapté le code pour que le scroll se fasse sur le scrollviewer dont ont connais la hauteur visuel. Cette solution permet de savoir si on est près du bord.

    Voici le code corrigé et à finaliser :

    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
     <!-- DIRECTORY CONTENT -->
     <ScrollViewer x:Name="SelecScroll" Grid.Row="2" 
         VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
         <Grid >
     
             <Canvas x:Name="SelectionCanvas"
                 IsHitTestVisible="False"
                 Margin="5" Panel.ZIndex="10"
                 Width="{Binding Width, ElementName=listBox}"
                 Height="{Binding Height, ElementName=listBox}"/>
     
             <!-- control independant à faire en fonction de l'affichage type -->
             <ListBox x:Name="listBox"
                 ItemsSource="{Binding FiltredContent}"
                 SelectionMode="Multiple"
                 SelectedItems="{Binding SelectedItems}"
                 HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                 Margin="5" >
     
                 <interactivity:Interaction.Behaviors>
                     <behaviors:LassoSelectionListBoxBehavior  SelectionBorderColor="Red"/>
                 </interactivity:Interaction.Behaviors>
     
                 <ItemsControl.Styles>
                     <Style Selector="ContentPresenter"  x:DataType="vm:DirContentItemViewModel">
                         <Setter Property="Margin" Value="10"/>
                         <Setter Property="Width" Value="128" />
                     </Style>
                 </ItemsControl.Styles>
     
                 <ListBox.ItemsPanel >
                     <ItemsPanelTemplate >
                         <WrapPanel Orientation="Horizontal" />
                     </ItemsPanelTemplate>
                 </ListBox.ItemsPanel>
     
             </ListBox>
     
             <TextBlock Text="Pas de fichier à afficher"
                 IsVisible="{Binding EmptyContent}"
                 Foreground="Red"
                 HorizontalAlignment="Center" VerticalAlignment="Center"
                 FontSize="15"/>
     
         </Grid>
     </ScrollViewer>
     <!-- END DIRECTORY CONTENT -->
    et le code du behavior

    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
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    using System;
    using System.Collections.Generic;
     
    using Avalonia;
    using Avalonia.Controls;
    using Avalonia.Input;
    using Avalonia.Media;
    using Avalonia.Xaml.Interactivity;
     
    using EBooKLab.Models.Core;
     
     
    namespace EBooKLab.Behaviors;
     
    public class LassoSelectionListBoxBehavior : Behavior<ListBox>
    {
     
        #region Members
     
        ListBox? _lbx;
        ScrollViewer? _scrollViewer;
        Canvas? _canvas;
     
        Border _selectionRectangle = new()
        {
            BorderBrush = Brushes.Blue,
            BorderThickness = new Thickness(1),
            Background = new SolidColorBrush(Colors.LightBlue, 0.3),
            IsHitTestVisible = false,
            IsVisible = false
        };
     
        SelectionType _mode = SelectionType.None;
        bool _isSelecting;
        Point _startPoint;
        readonly HashSet<object> _initialSelection = [];
        readonly HashSet<object> _newSelection = [];
     
        #endregion
     
        #region Properties
     
     
        public static readonly StyledProperty<IBrush> SelectionBorderColorProperty =
            AvaloniaProperty.Register<LassoSelectionListBoxBehavior, IBrush>(nameof(SelectionBorderColor), defaultValue: Brushes.Blue);
        public static readonly StyledProperty<double> SelectionBorderThicknessProperty =
            AvaloniaProperty.Register<LassoSelectionListBoxBehavior, double>(nameof(SelectionBorderThickness), defaultValue: 1);
     
        public static readonly StyledProperty<double> SelectionTransparancyProperty =
            AvaloniaProperty.Register<LassoSelectionListBoxBehavior, double>(nameof(SelectionTransparancy), defaultValue: 0.3);
     
        public static readonly StyledProperty<IBrush> SelectionBackgroundProperty =
            AvaloniaProperty.Register<LassoSelectionListBoxBehavior, IBrush>(nameof(SelectionBackground), defaultValue: Brushes.LightBlue);
     
     
        public IBrush SelectionBorderColor
        {
            get => GetValue(SelectionBorderColorProperty);
            set => SetValue(SelectionBorderColorProperty, value);
        }
     
        public double SelectionBorderThickness
        {
            get => GetValue(SelectionBorderThicknessProperty);
            set => SetValue(SelectionBorderThicknessProperty, value);
        }
     
        public double SelectionTransparancy
        {
            get => GetValue(SelectionTransparancyProperty);
            set => SetValue(SelectionTransparancyProperty, value);
        }
     
        public IBrush SelectionBackground
        {
            get => GetValue(SelectionBackgroundProperty);
            set => SetValue(SelectionBackgroundProperty, value);
        }
     
        #endregion
     
        #region Attaching 
     
        protected override void OnAttached()
        {
            base.OnAttached();
     
            if (AssociatedObject is not ListBox lbx) throw new ArgumentException("AssociatedObject is null or is not Type of Listbox");
            Grid? ct = lbx.Parent as Grid ?? throw new ArgumentException("AssociatedObject is not in a Grid");
            _scrollViewer = ct.Parent as ScrollViewer ?? throw new ArgumentException("AssociatedObject parent is not in a ScrollViewer");
            _canvas = ct.Children[0] as Canvas ?? throw new ArgumentException("AssociatedObject has no a canvas");
     
            //FIXME: Set to pressed
            _canvas.Children.Add(_selectionRectangle);
     
            _lbx = lbx;
            _lbx.PointerPressed += OnPointerPressedEvent;
            _lbx.PointerMoved += OnPointerMoved;
            _lbx.PointerReleased += OnPointerReleased;
        }
     
        protected override void OnDetaching()
        {
            if (_canvas is not null)
                _canvas = null;
     
            if (_lbx is not null)
            {
                _lbx.PointerPressed -= OnPointerPressedEvent;
                _lbx.PointerMoved -= OnPointerMoved;
                _lbx.PointerReleased -= OnPointerReleased;
     
                _lbx = null;
            }
     
            base.OnDetaching();
        }
     
        #endregion
     
     
        #region Mouse
     
        void OnPointerPressedEvent(object? sender, PointerPressedEventArgs e)
        {
            if (!e.GetCurrentPoint(_lbx).Properties.IsLeftButtonPressed ||
                _lbx is null || _canvas is null || _lbx.Items.Count == 0)
                return;
     
            SetMode(e.KeyModifiers);
            CreateSelectionShape();
     
            _startPoint = e.GetPosition(_lbx);
            _selectionRectangle.Width = 0;
            _selectionRectangle.Height = 0;
            Canvas.SetLeft(_selectionRectangle, _startPoint.X);
            Canvas.SetTop(_selectionRectangle, _startPoint.Y);
        }
     
        void SetMode(KeyModifiers key)
        {
            if (_lbx == null || _lbx.Items?.Count == 0)
                return;
     
            _isSelecting = true;
     
            if (key.HasFlag(KeyModifiers.Control))
                _mode = SelectionType.Toggle;
            else if (key.HasFlag(KeyModifiers.Shift))
                _mode = SelectionType.Add;
            else
            {
                _mode = SelectionType.New;
                _lbx.SelectedItems?.Clear();
            }
        }
     
     
     
     
     
     
        void CreateSelectionShape()
        {
            //FIXME :  
            /*_selectionRectangle = new()
            {
                BorderBrush = SelectionBorderColor,
                BorderThickness = new Thickness(SelectionBorderThickness),
                Background = new SolidColorBrush(SelectionBackground, SelectionTransparancy),
                IsHitTestVisible = false,
                IsVisible = false
            };
            
            // FIXME : _canvas.Children.Add(_selectionRectangle); => actuellement pas de renouvellement de la bordure donc ne peut ajouter 2 fois au canvas...*/
            _selectionRectangle.IsVisible = true; // Affichez le rectangle de sélection
        }
     
     
     
     
     
        void OnPointerMoved(object? sender, PointerEventArgs e)
        {
            if (!e.GetCurrentPoint(_lbx).Properties.IsLeftButtonPressed ||
                !_isSelecting || _lbx is null || _canvas is null || _scrollViewer is null)
                return;
     
            SetSelectionRectangle(e.GetPosition(_canvas));
            ScrollIfNeeded(e.GetPosition(_scrollViewer));
     
            SelectItems();
        }
     
        void SetSelectionRectangle(Point endPoint)
        {
            double x = Math.Min(_startPoint.X, endPoint.X);
            double y = Math.Min(_startPoint.Y, endPoint.Y);
            double width = Math.Abs(endPoint.X - _startPoint.X);
            double height = Math.Abs(endPoint.Y - _startPoint.Y);
            Canvas.SetLeft(_selectionRectangle, x);
            Canvas.SetTop(_selectionRectangle, y);
            _selectionRectangle.Width = width;
            _selectionRectangle.Height = height;
        }
     
        void ScrollIfNeeded(Point listBoxPoint)
        {
            if (_scrollViewer is null)
                return;
     
            // Marges pour activer le défilement automatique
            double scrollMargin = 20;
            double scrollSpeed = 20;
     
            // Obtenez la taille de la fenêtre de défilement
            var scrollHeight = _scrollViewer.Bounds.Height;
            var scrollWidth = _scrollViewer.Bounds.Width;
     
            if (listBoxPoint.X < scrollMargin) // Vérifiez si le curseur est proche du bord gauche
                _scrollViewer.Offset = new Vector(_scrollViewer.Offset.X - scrollSpeed, _scrollViewer.Offset.Y);
     
            else if (listBoxPoint.X > scrollHeight - scrollMargin) // Vérifiez si le curseur est proche du bord droit
                _scrollViewer.Offset = new Vector(_scrollViewer.Offset.X + scrollSpeed, _scrollViewer.Offset.Y);
     
            if (listBoxPoint.Y < scrollMargin) // Vérifiez si le curseur est proche du bord supérieur
                _scrollViewer.Offset = new Vector(_scrollViewer.Offset.X, _scrollViewer.Offset.Y - scrollSpeed);
     
            else if (listBoxPoint.Y > scrollHeight - scrollMargin) // Vérifiez si le curseur est proche du bord inférieur
                _scrollViewer.Offset = new Vector(_scrollViewer.Offset.X, _scrollViewer.Offset.Y + scrollSpeed);
     
        }
     
        #endregion
     
     
        void SelectItems()
        {
            if (_lbx is null || _lbx.Items?.Count == 0 || _canvas is null || _scrollViewer is null ||
                _selectionRectangle is null || _selectionRectangle?.Height == 0 || _selectionRectangle?.Width == 0 )
                return;
     
            double scrollOffset = _scrollViewer?.Offset.Y ?? 0;
            Rect itemBounds = new();
     
            foreach (var item in _lbx.Items!)
            {
                if (_lbx.ContainerFromItem(item!) is not Control container)
                    continue;
     
                itemBounds = new Rect(container.TranslatePoint(new Point(0, 0), _canvas) ?? new Point(), container.Bounds.Size);
                itemBounds = new Rect(itemBounds.X, itemBounds.Y - scrollOffset, itemBounds.Width, itemBounds.Height);
     
                SetSelecItem(item, _selectionRectangle!.Bounds.Intersects(itemBounds));
            }
     
        }
     
        void SetSelecItem(object? item, bool isInside)
        {
            switch(_mode)
            {
                case SelectionType.New:
                    if (isInside)
                    {
                        if (!_lbx!.SelectedItems!.Contains(item))
                            _lbx.SelectedItems.Add(item);
                    }
                    else
                    {
                        if (_lbx!.SelectedItems!.Contains(item))
                            _lbx.SelectedItems.Remove(item);
                    }
                    break;
                case SelectionType.Add:
                    if (isInside && !_lbx!.SelectedItems!.Contains(item))
                        _lbx.SelectedItems.Add(item);
                    break;
                case SelectionType.Toggle:
                    //FIXME : Fait scintillé l'affichage en inversant à chaque mouvement
                    /*                    if (isInside)
                        {
                            if (_lbx.SelectedItems!.Contains(item))
                                _lbx.SelectedItems.Remove(item);
                            else
                                _lbx.SelectedItems.Add(item);
                        }*/
                    if (isInside)
                    {
                        if (_newSelection.Contains(item))
                        {
                            if (_lbx!.SelectedItems!.Contains(item))
                                _lbx.SelectedItems.Remove(item);
                            _newSelection.Remove(item);
                        }
                        else
                        {
                            if (!_lbx!.SelectedItems!.Contains(item))
                                _lbx.SelectedItems.Add(item);
                            _newSelection.Add(item);
                        }
                    }
                        break;
            }
     
        }
     
        void OnPointerReleased(object? sender, PointerReleasedEventArgs e)
        {
            _isSelecting = false;
            //FIXME : _canvas?.Children.Clear();
            //_selectionRectangle = null;
            _initialSelection.Clear();
            _newSelection.Clear();
        }
     
    }

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

Discussions similaires

  1. Selection par clic de souris
    Par bilbonec dans le forum OpenGL
    Réponses: 7
    Dernier message: 16/04/2004, 01h25
  2. Select par mot-clés ou 1er lettre
    Par maadadi dans le forum Langage SQL
    Réponses: 4
    Dernier message: 11/02/2004, 11h50
  3. selection par date
    Par adgabd dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 12/01/2004, 11h28
  4. [TListBox] Selection par défaut
    Par Nuts07 dans le forum Composants VCL
    Réponses: 8
    Dernier message: 12/05/2003, 11h00
  5. Couleur de sélection par défaut
    Par sicard_51 dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 21/04/2003, 00h35

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