Как обновить ListBox с помощью INotifyPropertyChanged - PullRequest
2 голосов
/ 09 ноября 2011

У меня есть календарь, и я вложил элемент управления в элемент управления календари, чтобы я мог отображать события в ячейке сетки (дата), для которой я хочу создать событие.Календарь составляет 7 столбцов и 6 строк.Прямо сейчас я просто использую список для отображения события (Названия).Я могу добавлять элементы при запуске, но я хочу иметь возможность добавлять / удалять / изменять, когда программа уже запущена.Я пробовал INotifyPropertyChanged один раз, и я не мог понять это на всю жизнь.Если кто-то может взять то, что у меня есть, показать мне или дать советы о том, как я могу это сделать, я был бы очень признателен.

Класс, в который я могу добавить (элементы) перед запуском:

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

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

    }

Это окно (класс), которое появляется, когда я хочу добавить событие один разпрограмма уже запущена и работает.Мне нужно выяснить, как добавить элементы с помощью этого окна и как добавить его к определенной дате (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"    });

Это фактический XAML-календарь, где мне нужно связать все.

     </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; }
            }
       }        
  }

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Ответ Харша является верным для того, как вы реализуете INotifyPropertyChanged, однако вам нужно реализовать это только для отдельных свойств.Если вы хотите уведомить пользовательский интерфейс об изменении коллекции, используйте ObservableCollection class

Так что если у вас есть Label, содержащий Event.EventTitle, и вы хотите изменить EventTitle в коде-позволяет реализовать INotifyPropertyChanged на EventClass, чтобы при обновлении myEvent.EventTitle метка в пользовательском интерфейсе автоматически обновлялась до нового значения.

Если у вас есть ListBox (или ItemsControl)которую вы хотите автоматически обновлять при добавлении или удалении элементов в / из коллекции, просто привяжите ListBox к свойству ObservableCollection, что автоматически обновит пользовательский интерфейс при добавлении или удалении элементов из него.

Например,

<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>

В этом примере ваш класс Schedule будет иметь свойство с именем Events, которое является ObservableCollection<Event>.Чтобы добавить новое событие, вы можете использовать что-то вроде этого:

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" });
}

В качестве примечания, вы должны проверить некоторые .Net соглашения об именах

1 голос
/ 09 ноября 2011

Я думаю, что eventTitles, должно быть, имеет какую-то проблему с невыполнением интерфейса INotifyPropertyChanged, так что вот подробности для реализации.

Предположим, класс EventTitles

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));
        }
    }
}

Для дальнейшего ознакомления вы можете проверить на этом MSDN Post .

...