Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7682725
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T18:38:02+00:00 2026-05-31T18:38:02+00:00

Okay, I might be asking an age old question, but I did not get

  • 0

Okay, I might be asking an age old question, but I did not get my scenario described in any of them.

I have an Oject which can contain several child Objects. Eg. A Project obejct can have several Resource objects. I have an ObservaleCollection with super set of child obejcts (in my case Resource objects). I also have another ObservableCollection in Project object containing existing childs.

What is the best way to present this to user in WPF windows application? I also need to provide a way for them to chnage the mapping as well.

My initial idea was to use classic Double List approach, with two listboxes, but I am not sure how easy it would be to manipulate view layer alone.

[Resoure Collection]             [Resoure Collection in a Project]  
--------------------             ---------------------------------  
|Resource 1        |      >      |Resource 3                     |  
|Resource 2        |      >>     |Resource 4                     |  
|Resource 5        |      <      |                               |  
|Resource 6        |      <<     |                               |  
|Resource 7        |             |                               |  

I need similar UI for 4 more similar mappings of different objects. I tried to move this to a user control, but looks like I can’t have Generic collection (private ObservableCollection) in an UserControl.

Any ideas from experience members?

/**************************************************/
Edit: THis is what I got so far, note that I am going with UserControl since I need the same UI in multiple screens, and I feel UserCOntrol will give me more manageable code.

XAML for the user control

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="TimeTracker.ItemsSelectionLists"
             x:Name="ItemsSelectionControl">
    <Grid x:Name="LayoutRoot">
        <Grid Background="#FFF9FDFD"
              Margin="0,0,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="SourceHeading"
                       Grid.Column="0"
                       Margin="8,8,0,0"
                       TextWrapping="Wrap"
                       Text="Whole Team"
                       VerticalAlignment="Top" />
            <ListBox x:Name="SourceItemsList"
                     Grid.Column="0"
                     Margin="8,30,8,8"
                     MinWidth="150"
                     SelectionMode="Multiple"
                     ItemsSource="{Binding Path=Collection1}"/>
            <StackPanel Grid.Column="1"
                        Margin="0"
                        Orientation="Vertical"
                        VerticalAlignment="Center">
                <Button Content="&gt;"
                        Height="25"
                        Width="25" />
                <Button Content="&gt;&gt;"
                        Height="25"
                        Width="25" />
                <Button Content="&lt;"
                        Height="25"
                        Width="25" />
                <Button Content="&lt;&lt;"
                        Height="25"
                        Width="25" />
            </StackPanel>
            <TextBlock x:Name="TargetHeading"
                       Grid.Column="2"
                       Margin="8,8,8,0"
                       TextWrapping="Wrap"
                       Text="Current Team"
                       VerticalAlignment="Top" />
            <ListBox x:Name="SelectedItemsList"
                     Grid.Column="2"
                     Margin="8,30,8,8"
                     MinWidth="150"
                     ItemsSource="{Binding Path=Collection2}"/>
        </Grid>
    </Grid>
</UserControl>

Code:

/// <summary>
    /// Interaction logic for ItemsSelectionLists.xaml
    /// </summary>
    public partial class ItemsSelectionLists: UserControl
    {
        [Bindable(true)]

        internal ObservableCollection<TrackerItem> SourceList
        {
            get
            {
                return _vm.Collection1;
            }
            set
            {
                _vm.Collection1 = value;
            }
        }

        private readonly ViewModel _vm; 

        public ItemsSelectionLists()
        {
            this.InitializeComponent();
            _vm = new ViewModel();
            this.DataContext = _vm; 
        }
    }

    public class ViewModel : INotifyPropertyChanged
    {
        #region Properties

        private ObservableCollection<TrackerItem> _collection1;

        /// <summary> 
        /// This is the first collection. 
        /// </summary> 
        internal ObservableCollection<TrackerItem> Collection1
        {
            get
            {
                return _collection1;
            }

            set
            {
                if (value != _collection1)
                {
                    _collection1 = value;
                    NotifyPropertyChanged("Collection1");
                }
            }
        }

        private ObservableCollection<TrackerItem> _collection2;

        /// <summary> 
        /// This is the second collection. 
        /// </summary> 
        internal ObservableCollection<TrackerItem> Collection2
        {
            get
            {
                return _collection2;
            }

            set
            {
                if (value != _collection2)
                {
                    _collection2 = value;
                    NotifyPropertyChanged("Collection2");
                }
            }
        }

        #endregion

        #region Constructors

        /// <summary> 
        /// Default constructor. 
        /// </summary> 
        public ViewModel()
        {
            // Create initial collections. 

            // Populate first collection with sample data 
            _collection1 = new ObservableCollection<TrackerItem>();
            // Seconf collection is empty 
            _collection2 = new ObservableCollection<TrackerItem>();
        }

        #endregion

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion
    }

Main Window

<TabItem Header="Resource Allocation">
    <local:ItemsSelectionLists x:Name="ResourceSelection"/>
</TabItem>

Code

ResourceSelection.SourceList = MainObject.Resources;
//error CS0029: Cannot implicitly convert type 'System.Collections.ObjectModel.ObservableCollection<TimeTracker.Resource>' to 'System.Collections.ObjectModel.ObservableCollection<TimeTracker.TrackerItem>'
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T18:38:03+00:00Added an answer on May 31, 2026 at 6:38 pm

    It’s not graceful or polished, but here is a workable sample. If I made this polished I would have implemented true MVVM, but as a sample, this will get you started.

    XAML:

    <Window x:Class="TwoListboxes.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="800">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="120" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
    
            <ListBox x:Name="List1" Grid.Column="0" 
                     Height="200" Margin="10" 
                     SelectionMode="Multiple"
                     ItemsSource="{Binding Path=Collection1}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Name}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
    
            <StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center">
                <Button Content="&gt;" Width="60" Click="MoveRightEvent" />
                <Button Content="&gt;&gt;" Width="60" Click="MoveAllRightEvent" />
                <Button Content="&lt;&lt;" Width="60" Click="MoveAllLeftEvent" />
                <Button Content="&lt;" Width="60" Click="MoveLeftEvent" />
            </StackPanel>
    
            <ListBox x:Name="List2" Grid.Column="2" 
                     Height="200" Margin="10" 
                     ItemsSource="{Binding Path=Collection2}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Name}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Window>
    

    The code-behind:

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Members
    
        private readonly ViewModel<TrackerItem> _vm;
    
        #endregion
    
        public MainWindow()
        {
            // Get viewmodel and set context
            _vm = new ViewModel<TrackerItem>();
            _vm.Collection1 = new ObservableCollection<TrackerItem>
                {
                    new TrackerItem { Name = "Item1", Value = "1"},
                    new TrackerItem { Name = "Item2", Value = "2"},
                    new TrackerItem { Name = "Item3", Value = "3"},
                    new TrackerItem { Name = "Item4", Value = "4"},
                    new TrackerItem { Name = "Item5", Value = "5"},
                    new TrackerItem { Name = "Item6", Value = "6"},
                    new TrackerItem { Name = "Item7", Value = "7"},
                    new TrackerItem { Name = "Item8", Value = "8"},
                    new TrackerItem { Name = "Item9", Value = "9"},
                    new TrackerItem { Name = "Item10", Value = "10"}
                };
            this.DataContext = _vm;
    
            // Initialize UI
            InitializeComponent();
        }
    
        /// <summary>
        /// Moves selected items in a list from one collection to another.
        /// </summary>
        /// <param name="list"></param>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        private void MoveItems(ListBox list,
            ObservableCollection<TrackerItem> source,
            ObservableCollection<TrackerItem> destination)
        {
            if (list.SelectedItems.Count > 0)
            {
                // List for items to be removed.
                var hitList = new List<TrackerItem>();
    
                // Move items
                foreach (var selectedItem in list.SelectedItems)
                {
                    var item = selectedItem as TrackerItem;
                    if (item != null)
                    {
                        // Tag item for removal
                        hitList.Add(item);
    
                        // Check if item is in target list
                        var targetList = (from p in destination
                                          where p == item
                                          select p).ToList();
    
                        // Add to destination
                        if (!targetList.Any())
                        {
                            destination.Add(item);
                        }
                    }
                }
    
                // Remove items
                foreach (var hitItem in hitList)
                {
                    // Remove item
                    source.Remove(hitItem);
                }
            }
        }
    
        /// <summary>
        /// Moves all items from one list to another.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        private void MoveAllItems(
            ObservableCollection<TrackerItem> source,
            ObservableCollection<TrackerItem> destination)
        {
            // List for items to be removed.
            var hitList = new List<TrackerItem>();
    
            // Move items
            foreach (var item in source)
            {
                if (item != null)
                {
                    // Tag item for removal
                    hitList.Add(item);
    
                    // Check if item is in target list
                    var targetList = (from p in destination
                                      where p == item
                                      select p).ToList();
    
                    // Add to destination
                    if (!targetList.Any())
                    {
                        destination.Add(item);
                    }
                }
            }
    
            // Remove items
            foreach (var hitItem in hitList)
            {
                // Remove item
                source.Remove(hitItem);
            }
        }
    
        /// <summary>
        /// Click event: moves selected items to the right.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MoveRightEvent(object sender, RoutedEventArgs e)
        {
            MoveItems(List1, _vm.Collection1, _vm.Collection2);
        }
    
        /// <summary>
        /// Click event: moves all items to the right..
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MoveAllRightEvent(object sender, RoutedEventArgs e)
        {
            MoveAllItems(_vm.Collection1, _vm.Collection2);
        }
    
        /// <summary>
        /// Click event: moves all items to the left.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MoveAllLeftEvent(object sender, RoutedEventArgs e)
        {
            MoveAllItems(_vm.Collection2, _vm.Collection1);
        }
    
        /// <summary>
        /// Click event: moves selected items to the left.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MoveLeftEvent(object sender, RoutedEventArgs e)
        {
            MoveItems(List2, _vm.Collection2, _vm.Collection1);
        }
    }
    

    The ViewModel:

    public class ViewModel<T> : INotifyPropertyChanged
    {
        #region Properties
    
        private ObservableCollection<T> _collection1;
    
        /// <summary>
        /// This is the first collection.
        /// </summary>
        public ObservableCollection<T> Collection1
        {
            get { return _collection1; }
    
            set
            {
                if (value != _collection1)
                {
                    _collection1 = value;
                    NotifyPropertyChanged("Collection1");
                }
            }
        }
    
        private ObservableCollection<T> _collection2;
    
        /// <summary>
        /// This is the second collection.
        /// </summary>
        public ObservableCollection<T> Collection2
        {
            get { return _collection2; }
    
            set
            {
                if (value != _collection2)
                {
                    _collection2 = value;
                    NotifyPropertyChanged("Collection2");
                }
            }
        }
    
        #endregion
    
        #region Constructors
    
        /// <summary>
        /// Default constructor.
        /// </summary>
        public ViewModel()
        {
            // Create initial collections.
    
            // Populate first collection with sample data
            _collection1 = new ObservableCollection<T>();
    
            // Seconf collection is empty
            _collection2 = new ObservableCollection<T>();
        }
    
        #endregion
    
        #region INotifyPropertyChanged
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    
        #endregion
    }
    

    TrackerItem

    public class TrackerItem : INotifyPropertyChanged
    {
        private string _name;
    
        /// <summary>
        /// A name.
        /// </summary>
        public string Name
        {
            get { return _name; }
    
            set
            {
                if (value != _name)
                {
                    _name = value;
                    NotifyPropertyChanged("Name");
                }
            }
        }
    
        private string _value;
    
        /// <summary>
        /// A value.
        /// </summary>
        public string Value
        {
            get { return _value; }
    
            set
            {
                if (value != _value)
                {
                    _value = value;
                    NotifyPropertyChanged("Value");
                }
            }
        }
    
        #region INotifyPropertyChanged
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    
        #endregion
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Okay, so the answer to my question might not be the problem but here's
Okay, the question might seem dumb, but I'm asking it anyways. After struggling for
Okay, so this might be kind of strange but here's the question: I have
This might be a n00bish question, but whatever. Is okay to use exceptions for
Okay, this might be a very silly beginner question, but: I've got an ClassA,
okay this might be a pretty lame and basic question but its stuck in
Okay this is probably a rookie question, but I have never done GUI programming
okay, this might be a silly question. So I have some tuples of size
Okay, this might seem like a weird question, but bear with me. So I
Okay the question title may not have made sense... mostly because I don't know

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.