How do I program the Change selection event in a ListBox in WPF?

I have a list and I want to prevent the ListBox selection from being changed if the user has not finished certain tasks, this is the best explanation I can provide at this time, in WinForms that changed before and it has the option to cancel the event where we are could catch and undo even a selection change.

I thought I was inheriting the list and doing something, but internally all the functions in the Selector class are hidden, which I can see in the reflector, but I cannot inherit and override any methods!

+2


a source to share


6 answers


I took the MyListBox class out of the ListBox and added a SelectionChanging event, which is a cancellation event. Then I used MyListBoxItem as an ItemContainer in MyListBox, which handles the Left Mouse View event and raises the Change Selection event, by the cancel value, I mark the event as handled, which prevents a new selection, and also allows me to notify the user to do what -or.



+3


a source


Bind IsSelected

to a property in your view's model class and handle the case in the property setting device, for example:

public bool IsSelected
{
   get { return _IsSelected; }
   set
   {
       if (value && DisableSelection)
       {
          AlertUser();
       }
       else
       {
          _IsSelected = value;
       }
       OnPropertyChanged("IsSelected");
   }
}

      



Note that you are raising the event PropertyChanged

even if the property has not changed, since from a perspective it did change.

+1


a source


I know this does not directly answer your question, but in most cases (I had to make sure of the reason not for), I simply would not be able to control until the selection criteria were met.

This simple step removes much of the difficulty of determining what a value has changed and if it was a valid change, etc. If you allow editing the comboxbox (i.e. the value entered) it adds another layer of complexity.

Otherwise, this is a related discussion: How to prevent / undo a combobox value from being changed in C #?

0


a source


One solution would be to make the ListBox and ListBoxItems inactive until you are ready to change them. Here's a quick layout that did it:

XAML:

<StackPanel>
        <ListBox x:Name="LB">
            <ListBoxItem Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=Focusable}"  Content="item 1"/>
            <ListBoxItem Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=Focusable}" Content="item 2"/>
            <ListBoxItem Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=Focusable}" Content="item 3"/>
            <ListBoxItem Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=Focusable}" Content="item 4"/>
            <ListBoxItem Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=Focusable}" Content="item 5"/>
            <ListBoxItem Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=Focusable}" Content="item 6"/>
        </ListBox>
        <Button Content="Lock/Unlock" Click ="Button_Click"/>
    </StackPanel>

      

the code:

   private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (LB.Focusable == true)
            LB.Focusable = false;
        else
            LB.Focusable = true;
    }

      

0


a source


This is a bit of a hack, but I just used the PreviewMouseLeftButtonDown event.

In the handler, I had to ask the user if they were sure they wanted to leave. For some reason, after the message appears, whether e.handled is marked true or not, the selected event will not fire, something about that message. So, if the user confirms the navigation, I would use mouseclick to find the corresponding data item that was clicked (loop with the VisualTreeHelper until you find the ListBoxItem) and then manually select that item. If the user prefers not to navigate, just set e.handled to false (although the message popup seems to have the same effect.)

0


a source


I had the same need (ask the user if they really want to change the selected item in a single select ListBox) when certain criteria are not met. One choice is important, otherwise the code becomes more complex. I based my solution on tempy's answer, but moving the visual tree seemed too much, so I just used listBox.ItemContainerGenerator to ask the ListBox items if the mouse is over them and proceed accordingly:

    private void listBox_PreviewMouseDown(object sender, MouseButtonEventArgs e) {
        if (CheckIfCurrentlySelectedItemCanBeDeselected())
            // let things run normally
            return;

        var itemUnderMouse = GetListBoxItemUnderMouse(listBox);

        // check if there is no item under mouse
        // or if it is the currently selected item
        if (itemUnderMouse == null || itemUnderMouse.Content == currentItem)
            return;

        // always set Handled and take care of changing selection manually
        e.Handled = true;

        if (MessageBox.Show("The selected value is not valid, change selection?", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes) {
            // change the value manually
            lbArticles.SelectedItem = itemUnderMouse.Content;
        }
    }

    private ListBoxItem GetListBoxItemUnderMouse(ListBox lb) {
        foreach (object o in lb.Items) {
            ListBoxItem lbi = lb.ItemContainerGenerator.ContainerFromItem(o) as ListBoxItem;

            if (lbi != null && lbi.IsMouseOver) {
                return lbi;
            }
        }

        return null;
    }

      

0


a source







All Articles