78266

ListBox does not display the binding data

In my Xaml i have this,

<ComboBox x:Name="masterCB" HorizontalAlignment="Left" Margin="5,127,0,0" VerticalAlignment="Top" Width="106" Height="22" Background="White" ItemsSource="{Binding Masters}" FontSize="11" SelectedIndex="{Binding Action}"/> <Label Content="Select Action:" HorizontalAlignment="Left" VerticalAlignment="Top" Height="26" Width="116" Margin="0,151,0,0" Background="{x:Null}" FontWeight="Bold"/> <ListBox x:Name="actionBox" HorizontalAlignment="Left" Height="250" VerticalAlignment="Top" Width="116" Margin="5,177,0,0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding ActionList}" AlternationCount="2" MouseDoubleClick="actionBox_DoubleClick"> <ListBox.ItemTemplate> <DataTemplate> <Grid Background="{x:Null}"> <TextBlock Text="{Binding}" TextTrimming="WordEllipsis" TextWrapping="Wrap" Height="40" FontSize="11" /> </Grid> </DataTemplate> </ListBox.ItemTemplate> <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Style.Triggers> <Trigger Property="ItemsControl.AlternationIndex" Value="1"> <Setter Property="Background" Value="Silver"/> </Trigger> </Style.Triggers> </Style> </ListBox.ItemContainerStyle>

In my data class i have this,

private List<String> actionList; public int Action { get{return this.action;} set { action = value; populateActionList(); } } public List<String> ActionList { get { return actionList; } set { this.actionList = value; } private void populateActionList() { if (this.action == 0) { actionList = new List<String> { "Chinese", "Indian", "Malay", "Indian", }; if (this.action == 1) { actionList = new List<String> { "Dog", "Cats", "Pigs", "Horses", "Fish", "Lion"}; } }

When i do a printline, my actionList is changed, but the ListBox item is not set to my actionList. Would just like to know why and how come the UI does not update? I read somewhere that you would have to change to DataContext and ObservableCollections but i tried that one out and it still does not update. Does anyone know why?

Answer1:

Changing your code to the following, will do what you expect

private ObservableCollection<String> _actionList; public ObservableCollection<String> ActionList { get { if (_actionList == null) { _actionList = new ObservableCollection<String>(); } return actionList; } } private void populateActionList(){ if (this.action == 0) { ActionList.Clear(); ActionList.Add("Chinese"); ActionList.Add("Indian"); ActionList.Add("Malay"); ActionList.Add("Indian"); } if (this.action == 1){ ActionList.Clear(); ActionList.Add("Dog"); ActionList.Add("Cats"); ActionList.Add("Pigs"); ActionList.Add("Horses"); ActionList.Add("Fish"); ActionList.Add("Lion"); } }

Answer2:

I copied all of your code, and ran it in a new WPF app.

In order to fix your binding issue, there are two ways:

1st: make a Loaded event on your main window, with the following code:

private void Window_Loaded(object sender, RoutedEventArgs e) { DataContext = this; populateActionList(); }

this gives the following in my app:

<img src="https://i.stack.imgur.com/t5umP.png" alt="pic of app">

2nd: You can also bind this in XAML like so:

in your MainWindow.xaml:

Add the following to the window tag:

<strong>DataContext="{Binding RelativeSource={RelativeSource Self}}"</strong>

Then in your constructor, make sure you set your data before InitializeComponent() is run:

public MainWindow() { populateActionList(); InitializeComponent(); }

Answer3:

In your case, you can also work with Lists if you want, because you are replacing the whole list and not adding/removing single items. For that, you would have to use ObservableCollection, like Jehof wrote, which is automatically firing CollectionChanged events (not PropertyChanged) when add/remove/clear/replace actions are executed on the collection.

You need to change two things to get your code to work:

<ol> <li>Correctly implement INotifyPropertyChanged in your viewmodel. For each property that you databind, you will need to fire the PropertyChanged event in the setter. See my code below.</li> <li>Do not change your private actionList field, instead change your property ActionList, when you want bindings to be updated, because when you change your field, the PropertyChanged event is not fired.</li> </ol>

The thing to keep in mind is: Your UI listens to PropertyChanged and CollectionChanged events of the properties it is databound to. So if your UI does not get updated, these events are usually not fired.

ViewModel:

public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } // Masters private List<string> _masters = new List<string>() { "Actions 0", "Actions 1" }; public List<string> Masters { get { return _masters; } set { _masters = value; OnPropertyChanged("Masters"); } } // Action private int action; public int Action { get { return this.action; } set { action = value; PopulateActionList(); OnPropertyChanged("Action"); } } // ActionList private List<String> actionList; public List<String> ActionList { get { return actionList; } set { this.actionList = value; OnPropertyChanged("ActionList"); } } private void PopulateActionList() { if (this.action == 0) this.ActionList = new List<String> { "Chinese", "Indian", "Malay", "Indian" }; else if (this.action == 1) this.ActionList = new List<String> { "Dog", "Cats", "Pigs", "Horses", "Fish", "Lion" }; } }

Answer4:

ActionList should be ObservableCollection<string>.

You should set DataContext of your window to the object with property ActionList

Recommend

  • Using set() on an array
  • How to get a slug name for a page without creating an admin page menu
  • In ShellScript Assign Variable Based on Curl Output
  • Change only the image inside same div when option from dropdown is chosen
  • How to prevent a nib from loading if already in instance is loaded?
  • Writing CSV in perl
  • Google Chart: How to draw the vertical line for bar graph
  • Using an enum contained in a Cloud Endpoint model on a Android client
  • What's wrong with my datatrigger binding?
  • Do I need to reset a Perl hash index?
  • How to access EntityManager inside Entity class in EJB3
  • Splitting given String into two variables - php
  • What is Eclipse's Declaration View used for?
  • Counter field in MS Access, how to generate?
  • Possible to stop flickering java tooltip in heavyweight mode?
  • sending/ receiving email in Java
  • How to set my toolbar fixed while scrolling android
  • Javascript + PHP Encryption with pidCrypt
  • AT Commands to Send SMS not working in Windows 8.1
  • Cannot Parse HTML Data Using Android / JSOUP
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • trying to dynamically update Highchart column chart but series undefined
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • JTable with a ScrollPane misbehaving
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • Getting Messege Twice Using IMvxMessenger
  • Java static initializers and reflection
  • embed rChart in Markdown
  • apache spark aggregate function using min value
  • unknown Exception android
  • Sorting a 2D array using the second column C++
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • Observable and ngFor in Angular 2
  • How can i traverse a binary tree from right to left in java?
  • How can I use `wmic` in a Windows PE script?
  • failed to connect to specific WiFi in android programmatically
  • Unable to use reactive element in my shiny app
  • java string with new operator and a literal
  • How can I use threading to 'tick' a timer to be accessed by other threads?
  • How do I use LINQ to get all the Items that have a particular SubItem?