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

时间:2016-12-13 16:24:17

标签: c# wpf data-binding

我有几个窗口set -e trap 'echo "Error $?"' ERR ... # Simulate a command that fails by calling `exit` in a subshell. (exit 3) 设置为datacontext ItemsSource的集合中的特定项目。这些窗口包含试图绑定到ItemsControl中不同属性的文本框。但是,即使我正在观看值本身更新,文本框也不会反映任何更改。

这是我的datacontext,它位于我的MainWindow.xaml中。 ItemsControlItemsSource的集合,我将在下面发布。

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更新了各种属性。

在上面的MainWindow.xaml中也可以看到,当我点击ItemsControl中的按钮时,我会调用一个命令。此命令位于我的MainViewModel中,它调用此函数:

CurrentTime

因此,datacontext设置为ItemsSource中的项目。我已经确认数据在那里。

这是时间轴窗口的.xaml:

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

当指定属性中的值发生更改时,它们不会在<Window> <Grid> <TextBox IsReadOnly="True" Text="{Binding CurrentYear, Mode=OneWay}" /> <TextBox IsReadOnly="True" Text="{Binding CurrentDayOfYear, Mode=OneWay}" /> </Grid> </Window> 窗口的文本框中正确更新。尽管据我所知,使用断点和诸如此类的东西,它们正在datacontext中进行更新。

我不知道为什么它没有更新。

编辑:这是我如何更新积分(可能不是最好的方式,我愿意接受建议):

在我的主视图模型中:

Timeline

然后在我的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

上面应该反过来更新CurrentIteration通知的其他属性。

1 个答案:

答案 0 :(得分:1)

预计VehicleViewModel.SetData()中的这一行会更新CurrentTime,这会导致所有只读属性更新为#34;,为每个属性提升PropertyChanged

CurrentIteration = i;

CurrentTime中的setter会引发所有PropertyChanged次通知。但你永远不会打电话给那个二传手。 CurrentIteration setter只调用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();
    }
}