marko Grbovic
marko Grbovic

Reputation: 29

Binding from one ListBox to another ListBox?

I am trying to bind a ListBox to another ListBox within the same window. The left hand sided Listbox has data in it that one can select. But I want a user to be able to click on the item(s) in the left hand listbox and those same item(s) would be displayed in the other listbox on the right hand side.

Upvotes: 0

Views: 1263

Answers (2)

dytori
dytori

Reputation: 487

EDITED: Of course you can bind a UI property to another UI property (Dependency Property actually) using ElementName, but I recommend to bind the properties to one view model. See a simplified example below.

View model:

public ObservableCollection<ItemObject> Items  { get; set; }
public ObservableCollection<ItemObject> SelectedItems { get; set; }

Left:

<ListBox ItemsSource="{Binding Items}" SelectedItems="{Binding SelectedItems}" />

(Note that there is no SelectedItems dependency property actually. See question like: Select multiple items from a DataGrid in an MVVM WPF project)

Right:

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

This works fine. Furthermore, with this approach, the list on the right hand can be customized with ease (eg order, filter, ... by using CollectionView).

private ICollectionView _collectionView;
private ICollectionView _CollectionView {
    get { return _collectionView
        ?? (_collectionView = CollectionViewSource.GetDefaultView(SelectedItems)); }
}
public ICollectionView FilteredItems { 
    get { _CollecitionView.Filter(...); }
}

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

Such an MVVM approach is sometimes laborious, but eventually found as beneficial.

Upvotes: 2

ΩmegaMan
ΩmegaMan

Reputation: 31576

You name the first listbox, then any other control on the xaml will bind to that control using it's name in the ElementName attribute of the binding.

For example there are two listboxes and one text box. The top listbox has multiselections and those selection(s) are shown on the lower listbox. While the textbox only gets the first item selected.

enter image description here

<StackPanel Orientation="Vertical">
    <StackPanel.Resources>
        <converters:PathToFilenameConverter x:Key="FilenameConverter" />
        <x:Array x:Key="FileNames" Type="system:String">
            <system:String>C:\Temp\Alpha.txt</system:String>
            <system:String>C:\Temp\Beta.txt</system:String>
            <system:String>C:\Temp\Gamma.txt</system:String>
        </x:Array>
    </StackPanel.Resources>

    <ListBox  Name="lbFiles"
              SelectionMode="Multiple"
              ItemsSource="{StaticResource FileNames}"
              Margin="10"/>

    <ListBox ItemsSource="{Binding SelectedItems, ElementName=lbFiles }"  Margin="10" />

    <TextBlock Text="{Binding SelectedItem, 
                      ElementName=lbFiles,
                      Converter={StaticResource FilenameConverter}}"
               Margin="10" />

</StackPanel>

Note...the code is binding using the SelectedItems property for the lower list box and not SelectedItem used by the TextBlock.


As an aside, another answer has the use of an ObservableCollection, that is not needed unless the array is dynamically changing; otherwise any array can be used. Depending on loading, say from a VM, it may need to adheres to the INotifyPropertyChanged.

Upvotes: 1

Related Questions