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