0
votes

I have two listbox define below:

<ListBox x:Name="RemoteListBox" HorizontalAlignment="Right" Margin="0,88.5,8,0" 
             Width="382.5" 
             HorizontalContentAlignment="Stretch"                 
             ItemsSource ="{Binding RemoteItemsList}"                                 
             SelectedIndex="0">            
    </ListBox>
    <ListBox x:Name="LibraryListBox" 
             Margin="4.5,88.5,437,0"
             HorizontalContentAlignment="Stretch"
             ItemsSource="{Binding LibraryItemsList}"                 
             SelectedIndex="0">                      
    </ListBox>

My viewmodel

    private ObservableCollection<MotionTitleItem> _remoteItemsList;
    public ObservableCollection<MotionTitleItem> RemoteItemsList
    {
        get { return _remoteItemsList; }
        set
        {
            _remoteItemsList = value;
            NotifyPropertyChanged("RemoteItemsList");
        }
    }
    private ObservableCollection<MotionTitleItem> _libraryItemsList

    public ObservableCollection<MotionTitleItem> LibraryItemsList
    {
        get { return _libraryItemsList; }
        set
        {
            _libraryItemsList = value;
            NotifyPropertyChanged("LibraryItemsList");
        }
    }

I bind two ListBox ItemSource with a ObserverableCollection define below:

var listMotion = new ObservableCollection<MotionTitleItem>();                
foreach (MotionInfo info in listMotionInfo)
     {
          var motionTitleItem = new MotionTitleItem();                    
          listMotion.Add(motionTitleItem);                    
     }
 viewModel.RemoteItemsList = listMotion;
 viewModel.LibraryItemsList = listMotion;

MotionTitleItem is a custom user control. My problem is only the first ListBox with ItemSource binding with RemoteListItem displays the Item in UI, the other doest not. If I bind two ListBox ItemSource with 2 ObserverableCollection, the problem solved:

var listMotion = new ObservableCollection<MotionTitleItem>();
var listMotion2 = new ObservableCollection<MotionTitleItem>();
foreach (MotionInfo info in listMotionInfo)
     {
           var motionTitleItem = new MotionTitleItem();
           listMotion.Add(motionTitleItem);
           var motionTitleItem2 = new MotionTitleItem();
           listMotion2.Add(motionTitleItem2);
      }
 viewModel.RemoteItemsList = listMotion;
 viewModel.LibraryItemsList = listMotion2;

Could someone explain to me where is the point of the first scenario problem?

1
I just tried binding two ListBoxes to the same ObservableCollection. Worked for me. Look for binding errors in your output window, if it's there, what does it say? Also, if you are binding both of them to the same collection, why do you even need two properties in your view model? Just bind them both to the same property. It might be helpful if you post code for your view model.Tejas Sharma
There is no error with binding. I think my problem is about the ObserveableColection of custorm usercontrol. If i change to system usercontrol as TextBlock, it worked. Thanks for your suggestion. I will edit my code.Ka Boom
More code please (view model and view). Also, just as an fyi, in WPF, UserControls are different from CustomControls. I think you're a little confused with the terminology.Tejas Sharma
I've added view model.Ka Boom
Can't see much wrong with what you've posted so far other than the fact that you don't need to do the whole NotifyPropertyChanged kaboodle with ObservableCollections. Every time you add an item to an ObservableCollection, it updates any bindings.Tejas Sharma

1 Answers

1
votes

I don't know why you used two temporary list for this. You can directly add items to your Observable collection. Try this :

foreach (MotionInfo info in listMotionInfo)
 {
       viewModel.RemoteItemsList.Add(info);
       viewModel.LibraryItemsList.Add(info);
  }

Below, I tried to create the solution for you. I assumed the model MotionTitleItem.

public class MotionTitleItem 
{
string _name = string.Empty;

public string Name
{
  get { return _name; }
  set
  {
    _name = value;
    OnPropertyChanged("Name");
  }
}


public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyName)
{
  try
  {
    PropertyChangedEventHandler eventHandler = this.PropertyChanged;

    if (null == eventHandler)
      return;
    else
    {
      var e = new PropertyChangedEventArgs(propertyName);
      eventHandler(this, e);
    }
  }
  catch (Exception)
  {

    throw;
  }
}

}

My view model for this application is:

 public class MotionTitleItemViewModel : INotifyPropertyChanged
 {
ObservableCollection<MotionTitleItem> _remoteItemsList = new ObservableCollection<MotionTitleItem>();

public ObservableCollection<MotionTitleItem> RemoteItemsList
{
  get { return _remoteItemsList; }
  set { _remoteItemsList = value; }
}

ObservableCollection<MotionTitleItem> _libraryItemsList = new ObservableCollection<MotionTitleItem>();

public ObservableCollection<MotionTitleItem> LibraryItemsList
{
  get { return _libraryItemsList; }
  set { _libraryItemsList = value; }
}

public MotionTitleItemViewModel()
{
  MotionTitleItem motion;
  for (int i = 0; i < 10; i++)
  {
    motion = new MotionTitleItem();
    motion.Name = "Name " + i.ToString();

    this.LibraryItemsList.Add(motion);
    this.RemoteItemsList.Add(motion);
  }     
}

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyName)
{
  try
  {
    PropertyChangedEventHandler eventHandler = this.PropertyChanged;

    if (null == eventHandler)
      return;
    else
    {
      var e = new PropertyChangedEventArgs(propertyName);
      eventHandler(this, e);
    }
  }
  catch (Exception)
  {

    throw;
  }
} }

My View is :

<Window x:Class="WPFExperiments.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox x:Name="RemoteListBox" HorizontalAlignment="Right" Margin="0,0.5,8,0" 
         Width="382.5" 
         HorizontalContentAlignment="Stretch"                 
         ItemsSource ="{Binding RemoteItemsList}"                                 
         SelectedIndex="0">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="LibraryListBox" 
         Margin="4.5,0.5,437,0"
         HorizontalContentAlignment="Stretch"
         ItemsSource="{Binding LibraryItemsList}"                 
         SelectedIndex="0">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>

In code behind of this window i set DataContext to view model.

public partial class MainWindow : Window
{
public MainWindow()
{
  InitializeComponent();
  this.DataContext = new MotionTitleItemViewModel();
}}

This code is working for me. Here is screenshot of the output.

enter image description here

Vote this answer if you find it useful.

Have fun!