ObservableCollection не обновляется

#c# #wpf #xaml #observablecollection

#c# #wpf #xaml #observablecollection

Вопрос:

Я чувствую, что я действительно близок к тому, чтобы заставить это работать. У меня есть календарь, я хочу, чтобы пользователь мог выбрать месяц из выпадающего списка и показать календарь на эту дату. Прямо сейчас ничего не отображается, независимо от того, что я выбираю из выпадающего списка. Я могу заставить его работать, используя listbox и событие кнопки, но на самом деле он не обновляет его, просто очищая и отображая выбранный новый месяц. Это неправильный способ сделать это. Я потратил на это много времени, и если кто-нибудь может посмотреть и, возможно, дать мне несколько советов, я был бы очень признателен.

———Класс модели———

          public partial class SchedulePage : Page, INotifyPropertyChanged 
{
    public int pick2;
     public event PropertyChangedEventHandler PropertyChanged;
    MainWindow _parentForm;
    public int pick;
    Schedule sched = new Schedule();

    static GregorianCalendar _gc = new GregorianCalendar();


   public SchedulePage(MainWindow parentForm)
    {
        InitializeComponent();





    //    this.PropertyChanged  = comboMonth_SelectionChanged;


        pick = Convert.ToInt32(comboMonth.SelectedItem);
        _parentForm = parentForm;



    }

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

    private int _nameofmonth ;

    public int NameofMonth
    {
        get
        {
            return this._nameofmonth;
        }

        set
        {
            if (value != this._nameofmonth)
            {
                this._nameofmonth = value;
                NotifyPropertyChanged("NameofMonth");
            }
        }
    }


 // void TheViewModel_PropertyChanged(object src, PropertyChangedEventArgs e)
    private void comboMonth_SelectionChanged(object sender, SelectionChangedEventArgs e)
  {
    //{

      //  if (e.PropertyName == "NameofMonth")
       // {
            //var date = new DateTime(2011, 11, 1);
            //makeCalender(date);

        _parentForm.bindings.schedule.Clear();
            var t = new List<Schedule>();
            DateTime curr = DateTime.Now;
            int jeez = comboMonth.SelectedIndex 1;
            //  comboMonth.Items.Add(curr.Month);
            DateTime newcurr = new DateTime(2011, NameofMonth 1, 1);
            //   pickdate = datePickercal.SelectedDate;
            //  DateTime newcurr = new DateTime(curr.Year, curr.Month, 1);
            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 == NameofMonth 1; 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();
                t.Add(sched);

                _parentForm.bindings.schedule.Add(new Schedule { WeekNo = newcurr.GetWeekOfMonth() - 1, WeekDay = (int)newcurr.DayOfWeek, day = newcurr.Day.ToString() });

            }
            lblDate.Content = (newcurr.Month - 1)   "/"   newcurr.Year;
            //testGrid.ItemsSource = t;
            comboMonth.DataContext = _parentForm.bindings;
            DataContext = _parentForm.bindings;

       // }

    }
 

—-Часть XAML——

    <ComboBox  SelectedIndex="{Binding NameofMonth}" Grid.ColumnSpan="2" Height="23" HorizontalAlignment="Left" Margin="6,0,0,0" Name="comboMonth" VerticalAlignment="Top" Width="120" SelectionChanged="comboMonth_SelectionChanged">
            <ComboBoxItem Content="1" IsSelected="False" />
            <ComboBoxItem Content="2" />
            <ComboBoxItem Content="3" />
            <ComboBoxItem Content="4" />
            <ComboBoxItem Content="5" />
            <ComboBoxItem Content="6" />
            <ComboBoxItem Content="7" />
            <ComboBoxItem Content="8" />
            <ComboBoxItem Content="9" />
            <ComboBoxItem Content="10" />
            <ComboBoxItem Content="11" IsSelected="False" />
            <ComboBoxItem Content="12" />
        </ComboBox>
 

Комментарии:

1. Работает ли это, если вы измените SelectedIndex="{Binding NameofMonth}" на SelectedIndex="{Binding Path=NameofMonth, Mode=OneWayToSource}" или SelectedIndex="{Binding Path=NameofMonth, Mode=TwoWay}" ?

2. Нет, я пробовал оба способа. Для любого месяца, который я выберу, он покажет январь, но после этого ничего не произойдет.

3. Действительно ли привязка работает? т. е. есть ли ошибки? Вы отлаживали его ?

4. Я не уверен в привязке выпадающего списка. Однако все остальное, что связано, является правильным. Логика того, как календарь создает себя, верна. Это как-то связано с тем, как я использую PropertyChangedEventArgs .

5. Я создаю свойство (NameofMonth), и пользователь выбирает месяц из выпадающего списка, и календарь должен обновляться и отображаться для этой даты

Ответ №1:

Вам нужно сделать так, чтобы ваш класс poco, который используется в вашей ObservableCollection, реализовал INotifyChanged.

Пример:

 <viewModels:LocationsViewModel x:Key="viewModel" />
.
.
.    
<ListView
    DataContext="{StaticResource viewModel}"
    ItemsSource="{Binding Locations}"
    IsItemClickEnabled="True"
    ItemClick="GroupSection_ItemClick"
    ContinuumNavigationTransitionInfo.ExitElementContainer="True">

    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Margin="0,0,10,0" Style="{ThemeResource ListViewItemTextBlockStyle}" />
                <TextBlock Text="{Binding Latitude, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{ThemeResource ListViewItemTextBlockStyle}" Margin="0,0,5,0"/>
                <TextBlock Text="{Binding Longitude, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{ThemeResource ListViewItemTextBlockStyle}" Margin="5,0,0,0" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

public class LocationViewModel : BaseViewModel
{
    ObservableCollection<Location> _locations = new ObservableCollection<Location>();
    public ObservableCollection<Location> Locations
    {
        get
        {
            return _locations;
        }
        set
        {
            if (_locations != value)
            {
                _locations = value;
                OnNotifyPropertyChanged();
            }
        }
    }
}

public class Location : BaseViewModel
{
    int _locationId = 0;
    public int LocationId
    {
        get
        {
            return _locationId;
        }
        set
        {
            if (_locationId != value)
            {
                _locationId = value;
                OnNotifyPropertyChanged();
            }
        }
    }

    string _name = null;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if (_name != value)
            {
                _name = value;
                OnNotifyPropertyChanged();
            }
        }
    }

    float _latitude = 0;
    public float Latitude 
    { 
        get
        {
            return _latitude;
        }
        set
        {
            if (_latitude != value)
            {
                _latitude = value;
                OnNotifyPropertyChanged();
            }
        }
    }

    float _longitude = 0;
    public float Longitude
    {
        get
        {
            return _longitude;
        }
        set
        {
            if (_longitude != value)
            {
                _longitude = value;
                OnNotifyPropertyChanged();
            }
        }
    }
}

public class BaseViewModel : INotifyPropertyChanged
{
    #region Events
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(memberName));
        }
    }
}