#961 – A ListBox Has Three Available Selection Modes

By default, a user can select one item at a time in a ListBox.

961-001

You can use the SelectionMode property of the ListBox to allow the user to select multiple items.  By default, the SelectionMode property has a value of SelectionMode.Single, allowing the user to select a single item.

You can set SelectionMode to Extended, allowing a user to select multiple items, as follows:

  • A mouse left-click selects a single new item, unselecting all previously selected items
  • Control + left-click selects/unselects an additional item.  Previously selected items remain selected.
  • Shift + left-click selects all items between the most recently selected item and the one being clicked (inclusive).  Previously selected items not in this range are unselected.
  • Control + Shift + left-click selects all items within a range without unselecting previously selected items

961-002

Setting SelectionMode to Multiple allows selecting multiple items by left-clicking:

  • Left-clicking an item selects or unselects the item
Advertisements

#960 – A ListBox Can Store Objects of Different Types

You’ll most often bind the contents of a ListBox to a collection of items that are all of the same type.  You can, however, add different types of objects to the same ListBox.  Items in a ListBox can be either standard CLR objects or objects that derive from UIElement.

In the example below, we add several different types of objects to a ListBox.

    <ListBox Margin="15">
        <ListBoxItem>Simple string</ListBoxItem>
        <local:Actor FullName="Liam Neeson" BirthYear="1952" KnownFor="Schindler's List"/>
        <Button Content="Click Me"/>
        <TextBox Text="zzz" Width="100"/>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Username:"/>
            <TextBox Width="100" Margin="5,0"/>
        </StackPanel>
    </ListBox>

960-001
This example is not very typical, but points out that you can add any type of object that you like to a ListBox.  Note that the user can also select any item, whether the item is a string or a user interface element.

#959 – ListBox Basics

You can use a ListBox control to allow a user to select one or more items from a larger list of items.  The ListBox displays some subset of the items, with additional items visible by using scrollbars.

959-001

 

You typically populate a ListBox using data binding, setting its ItemsSource property.  Optionally, you can use the DisplayMemberPath property to indicate which property on the bound items is to be used in generating the text within the ListBox.

The Items property of the ListBox contains a collection of the items displayed in the list.  You typically use the SelectedItemSelectedItems, or SelectedIndex properties to access one or more items that a user has selected.

Instead of simple strings, each item in the ListBox can instead be displayed as a more complex user interface element.

959-002

#958 – Three Ways to Populate a List Control

There are three general ways that you can populate a list-based control with some content:

  • Add items in XAML
  • Add items in code
  • Use data binding  (preferred method, most flexible)

For example, to add several items to a ListBox from XAML:

    <ListBox>
        <ListBoxItem>Augustus</ListBoxItem>
        <ListBoxItem>Tiberius</ListBoxItem>
        <ListBoxItem>Caligula</ListBoxItem>
    </ListBox>

To add the same items from code:

    <ListBox Name="lbMyListBox"/>

 

            lbMyListBox.Items.Add("Augustus");
            lbMyListBox.Items.Add("Tiberius");
            lbMyListBox.Items.Add("Caligula");

Finally, to use data binding to add the items:

    <ListBox ItemsSource="{Binding Emperors}"/>

 

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private string[] emperors;
        public string[] Emperors
        {
            get { return emperors; }
            set
            {
                if (value != emperors)
                {
                    emperors = value;
                    RaisePropertyChanged("Emperors");
                }
            }
        }

        public MainWindow()
        {
            this.InitializeComponent();
            this.DataContext = this;

            Emperors = new string[]
                {"Augustus",
                 "Tiberius",
                 "Caligula"};
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        private void RaisePropertyChanged(string propName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

958-001

#957 – A Survey of Some List-Based Controls

WPF includes a variety controls that can display lists of items, all of which inherit from ItemsControl.  Below is a sampling of some of these controls.

ItemsControl is the base class for all of the list-based controls and provides basic support for storing a collection of items and displaying them in a simple list.

957-001

 

HeaderedItemsControl displays a list of items along with some sort of header (typically displayed above the items).

957-002

 

ToolBar contains a collection of items that a user can interact with.

957-003

 

Menu and MenuItem allow displaying a list of selectable items in a menu.

957-004

 

ComboBox allows selecting an item from a dropdown list.

957-005

 

ListBox allows selecting an item from a visible list.

957-006

 

DataGrid displays a collection of items in a tabular format.

957-007

 

TabControl groups user interface content into a set of selectable tabs.

957-008

 

TreeView displays a collection of items as a hierarchy.

957-009

#956 – PasswordBox Stores Password as a SecureString

When you use the PasswordBox control to let a user enter a password, the resulting password is stored in a SecureString.  SecureString allows storing confidential data in memory in a more secure manner than is possible with the string data type.

If the security of the string entered into a PasswordBox is important, you should avoiding converting the password into a managed type.  You can access the entered password as a SecureString using the SecurePassword property, which returns a SecureString.

You can also cause the password stored in a PasswordBox to be decrypted and stored as a string by using the Password property.  Since copying the confidential data into a managed type is not as secure as letting it remain stored on the unmanaged heap, within the SecureString, you should only use the Password property if the security of the data is not critical.

#955 – Getting Data Out of a SecureString

Confidential data stored in an instance of the SecureString type is stored in memory on the unmanaged heap, in an encrypted form.

If you need to work with the data in an unencrypted form, you can read the data out of the SecureString into an unmanaged string (BSTR).  Once you are finished working with the confidential string data, you should zero out the memory where it was stored.

Below is an example of using the Marshal.SecureStringToBSTR method to work with string data stored in a SecureString.

        private void DoSomethingWithSecureStringData(SecureString secStr)
        {
            // using System.Runtime.InteropServices
            IntPtr unmStr = Marshal.SecureStringToBSTR(secStr);

            try
            {
                // Do something with unmanaged confidential string here.
            }
            finally
            {
                Marshal.ZeroFreeBSTR(unmStr);
            }
        }

When you call the SecureStringToBSTR method, the SecureString object decrypts its data and copies it to a new BSTR, before re-encrypting it.