新窗口中的文本框当属性在其DataContext中更改时不会更新



我有几个窗口,其 datacontext设置为ItemsControlItemsSource中的集合中的特定项目。这些窗口包含试图绑定到datacontext中不同属性的文本框。但是,即使我本身要查看值更新,文本框也不会反映任何更改。

这是我的mainwindow.xaml内部的ItemsControlItemsSourceVehicleModel.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));
        }
    }
}

如上所述,我基于CurrentIterationCurrentTime更新了各种属性。

也可以在我的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();
    }
}

最新更新