我有几个窗口,其 datacontext
设置为ItemsControl
的ItemsSource
中的集合中的特定项目。这些窗口包含试图绑定到datacontext
中不同属性的文本框。但是,即使我本身要查看值更新,文本框也不会反映任何更改。
这是我的mainwindow.xaml内部的ItemsControl
。ItemsSource
是VehicleModel.cs
的集合,我将在下面发布。
<Window>
</Grid>
<ItemsControl ItemsSource="{Binding VehicleCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}},
Path=DataContext.ShowTimeWindowCmd}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource converter}">
<Binding Path="NowTime" />
<Binding />
<Binding Path="Name" />
</MultiBinding>
</Button.CommandParameter>
</Button>
</Grid>
</DateTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
这是持有数据的模型。
public class VehicleModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private List<double> _nowTime = new List<double>();
public List<double> NowTime
{
get { return _nowTime; }
set { _nowTime = value; OnPropertyChanged("Nowtime"); }
}
private int _currentIteration;
public int CurrentIteration //used to hold current index of the list of data fields
{
get { return _currentIteration; }
set
{
_currentIteration = value;
OnPropertyChanged("CurrentIteration");
OnPropertyChanged("CurrentTime");
}
}
private DateTime _firstTime; //holds the first record time in the ramp file
public DateTime FirstTime
{
get { return _firstTime; }
set { _firstTime = value; OnPropertyChanged("FirstTime"); }
}
private DateTime _lastTime; //holds the last record time in the ramp file
public DateTime LastTime
{
get { return _lastTime; }
set { _lastTime = value; OnPropertyChanged("LastTime"); }
}
public DateTime CurrentTime
{
get { return DateTime.FromOADate(NowTime[CurrentIteration]); }
set
{
if ((value < FirstTime) || (value > LastTime))
{
CurrentTime = FirstTime;
}
else
{
NowTime[CurrentIteration] = value.ToOADate();
}
OnPropertyChanged("CurrentTime");
OnPropertyChanged("CurrentYear");
OnPropertyChanged("CurrentDayOfYear");
OnPropertyChanged("CurrentHour");
OnPropertyChanged("CurrentMinute");
OnPropertyChanged("CurrentSecond");
}
}
public int CurrentYear
{
get { return CurrentTime.Year; }
}
public int CurrentDayOfYear
{
get { return CurrentTime.DayOfYear; }
}
public int CurrentHour
{
get { return CurrentTime.Hour; }
}
public int CurrentMinute
{
get { return CurrentTime.Minute; }
}
public int CurrentSecond
{
get { return CurrentTime.Second; }
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
如上所述,我基于CurrentIteration
和CurrentTime
更新了各种属性。
也可以在我的mainwindow.xaml中看到,在单击itemscontrol中的按钮时,我调用命令。此命令位于"我的My MainViewModel"中,该命令调用此功能:
public void ShowTimeWindow(object parameter)
{
var values = (object[])parameter;
List<double> xValues = (List<double>)values[0];
string winTitle = (string)values[2];
Timeline newTimeLine = new Timeline(xValues);
newTimeLine.DataContext = values[1]; //this is an item in the ItemsSource
newTimeLine.Show();
}
因此,DataContext设置为项目源中的项目。我已经验证了数据在那里。
这是时间轴窗口的.xAML:
<Window>
<Grid>
<TextBox IsReadOnly="True"
Text="{Binding CurrentYear,
Mode=OneWay}" />
<TextBox IsReadOnly="True"
Text="{Binding CurrentDayOfYear,
Mode=OneWay}" />
</Grid>
</Window>
当指定属性中的值更改时,在Timeline
Windows的文本框中未正确更新它们。据我所知,使用断点和其他内容,它们正在DataContext中进行更新。
我没有关于为什么不更新的想法。
编辑:这是我如何更新点的方式(可能不是最好的方法,我对建议开放):
在我的MainViewModel中:
public void SetData(int i) //i is just a constantly updated integer in my mainviewmodel
{
foreach (VehicleModel vehicle in VehicleCollection)
{
vehicle.SetData(i);
}
}
然后在我的VehicleMode.cs
类中:
public void SetData(int i)
{
CurrentIteration = i;
}
以上应依次更新当前属性通知的其他属性。
VehicleViewModel.SetData()
中的这一行预计将更新CurrentTime
,该行通过为每个人升起PropertyChanged
,从而导致所有可读属性"更新"。
CurrentIteration = i;
CurrentTime
中的设置器提高了所有这些PropertyChanged
通知。但是您永远不会打电话给那个固定器。CurrentIteration
设置器仅调用OnPropertyChanged("CurrentTime")
。
这是一个快速修复。如果是我,我可能会做以下的事情,或者我可能会更倾向于使CurrentIteration
Setter明确设置CurrentTime
。通常,如果属性具有setter,则唯一的曾经通过setter更改它。不过,我不明白您的表现足够好,无法正确编写。
protected void OnCurrentTimeChanged()
{
OnPropertyChanged("CurrentTime");
OnPropertyChanged("CurrentYear");
OnPropertyChanged("CurrentDayOfYear");
OnPropertyChanged("CurrentHour");
OnPropertyChanged("CurrentMinute");
OnPropertyChanged("CurrentSecond");
}
public DateTime CurrentTime
{
get { return DateTime.FromOADate(NowTime[CurrentIteration]); }
set
{
if ((value < FirstTime) || (value > LastTime))
{
CurrentTime = FirstTime;
}
else
{
NowTime[CurrentIteration] = value.ToOADate();
}
OnCurrentTimeChanged();
}
}
private int _currentIteration;
public int CurrentIteration //used to hold current index of the list of data fields
{
get { return _currentIteration; }
set
{
_currentIteration = value;
OnPropertyChanged("CurrentIteration");
OnCurrentTimeChanged();
}
}