TMan
TMan

Reputation: 4122

How to update ListBox using INotifyPropertyChanged

I have a calender and I nested a itemscontrol within the calendars itemscontrol so that I can display events in the gridcell(date) that I want to make an event for. The calender is 7 columns and 6 rows. Right now I'm just using a listbox to actually display the event(Titles). I can add items on startup but I want to be able to add/remove/change once the program is already running. I have tried INotifyPropertyChanged once before and I could not figure it out for the life of me. If someone can take what i have and show me or give me tips on how I can do this, I would really appreciate it.

The class where I can add(items) before startup:

public class eventProperties : ObservableCollection<eventsTitles>
{
    //public string Eventer { get; set; }

    public eventProperties() : base() 
    {
        Add(new eventsTitles("First Test"));
        Add(new eventsTitles("First Test#2"));

    }

This is window(class) that pops up when I want to add an event once the program is up and running already. I need to figure out how to add items from using this window and how to add it to a certain date(gridcell)

    public Event(MainWindow parentform)
    {

        InitializeComponent();
        _parentForm = parentform;
        //this.month = month;
        //this.day = day;
        //this.year = year;
        lblCreateEvent.Content = "Create Event For " + month + " / " + day + " / " + year;

    }

    private void btnSubmit_Click(object sender, RoutedEventArgs e)
    {
        month = Convert.ToInt32(txtMonth.Text);
        day = Convert.ToInt32(txtDay.Text);
        year = Convert.ToInt32(txtYear.Text);



        Schedule sched = new Schedule();
        DateTime curr = DateTime.Now;
        int[] m = new int[7];
        DateTime newcurr = new DateTime(year, month, day);

        var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
        var ms = cal.GetWeekOfYear(new DateTime(newcurr.Year, newcurr.Month, 1), System.Globalization.CalendarWeekRule.FirstDay, System.DayOfWeek.Sunday);

           // for (var i = 1; newcurr.Month == 11; newcurr = newcurr.AddDays(1))
           // {

                var month_week = (newcurr.Day / 7);
                sched.MonthWeek = newcurr.GetWeekOfMonth().ToString();
                sched.Month = newcurr.Month.ToString();
                sched.Year = newcurr.Year.ToString();
                sched.day = newcurr.Day.ToString();
                sched.WeekOfYear = cal.GetWeekOfYear(newcurr, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString();
                sched.dayofweek = newcurr.DayOfWeek.ToString();


                //Here is where the calender is created. By looping through all the days in the selected month it will find the weeknumber and day of the week -->
                // that that particular date belongs to and place in the correct gridcell.
                _parentForm.bindings.schedule.Add(new Schedule { WeekNo = newcurr.GetWeekOfMonth() - 1, WeekDay = (int)newcurr.DayOfWeek, day = newcurr.Day.ToString(), eventTitle = "Camper Calender"    });

This is the actual calender XAML where I need to bind everything.

     </customgridcontrol:GridControl>


     </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Button Content="{Binding day}" Width="175" HorizontalAlignment="Stretch" VerticalAlignment="Top" VerticalContentAlignment="Top" HorizontalContentAlignment="Left" Name="btnCalenderDate" Click="btnCalenderDate_Click" Loaded="btnCalenderDate_Loaded" Height="18" FontSize="10" FontWeight="Bold">
                        </Button>

                        <ItemsControl  Height="60" VerticalAlignment="Stretch">
                            <ItemsControl.Resources>
                                <src:eventProperties x:Key="dataList"/>
                            </ItemsControl.Resources>
                            <ItemsControl.Items>
                                <ListBox ItemsSource="{Binding Source= {StaticResource dataList} }" DisplayMemberPath="EventTitle" VerticalAlignment="Top" IsSynchronizedWithCurrentItem="True">            
                                </ListBox>
                            </ItemsControl.Items>
                        </ItemsControl>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
     <!-- ItemContainerStyle -->
        <ItemsControl.ItemContainerStyle>

            <Style >        
                    <Setter Property="Grid.Column" Value="{Binding WeekDay}"  />
                <Setter Property="Grid.Row" Value="{Binding WeekNo}" />
            </Style>
            </ItemsControl.ItemContainerStyle>
    </ItemsControl>

eventTitles Class

  namespace Camp_
  {
       public class eventsTitles
       {
            public string eventTitle {get; set;} 

            public eventsTitles()//String ev)
            {
               // this.eventTitle = ev;
            }

            public string EventTitle
            {
                get { return eventTitle; }
                set { eventTitle = value; }
            }
       }        
  }

Upvotes: 2

Views: 4583

Answers (2)

Rachel
Rachel

Reputation: 132558

Harsh's answer is correct for how you implement INotifyPropertyChanged, however you only need to implement that for single properties. If you're looking to notify the UI that a Collection has changed, use the ObservableCollection class

So if you had a Label containing Event.EventTitle, and you wanted to change the EventTitle in the code-behind, you would implement INotifyPropertyChanged on the EventClass so that when you updated myEvent.EventTitle the Label in the UI would automatically update to the new value.

If you have a ListBox (or ItemsControl) which you want to automatically update when you add or delete items to/from a Collection, simply bind the ListBox to an ObservableCollection property, which will automatically update the UI when items get added or removed from it.

For example,

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <StackPanel>
         <Button Content="{Binding day}" Click="AddEvent" />

         <ItemsControl Height="60" ItemsSource="{Binding Events}">
             <ItemsControl.ItemTemplate>
                 <DataTemplate>
                    <TextBlock Text="{Binding EventTitle}" />
                 <DataTemplate>
             </ItemsControl.ItemTemplate>
         </ItemsControl>
        </StackPanel>
    </DataTemplate>
</ItemsControl.ItemTemplate>

In this example, your Schedule class would have a property called Events which is an ObservableCollection<Event>. To add a new event you can use something like this:

void AddEvent(object sender, EventArgs e)
{
    // Get the DataContext for the Button, which should be of type Schedule
    Schedule day = (sender as Button).DataContext as Schedule;

    // Add New Event. Since this is an ObservableCollection, UI will automatically update
    day.Events.Add(new Event { EventTitle = "Test Event" });
}

As a side note, you should check out some .Net naming conventions

Upvotes: 2

Harsh Baid
Harsh Baid

Reputation: 7249

I am thinking that eventTitles must be having some issue of not implementing INotifyPropertyChanged interface so here is the details for implementing.

Supposing eventTitles class

public class eventTitles : INotifyPropertyChanged
{
    private string _eventtitle = string.Empty;

    public string EventTitle
    {
       get {return _eventtitle;}

        set
        {
            if (value != _eventtitle)
            {
                _eventtitle = value;
                NotifyPropertyChanged("EventTitle");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

For further reference you could check at this MSDN Post.

Upvotes: 2

Related Questions