2016-12-13 24 views
0

我有幾個窗口,其datacontext設置爲ItemsControlItemsSource集合中的特定項目。這些窗口包含試圖綁定到datacontext中不同屬性的文本框。但是,即使我正在觀察值本身的更新,文本框也不會反映任何更改。在新窗口中的文本框不更新當其數據環境中的屬性更改時

這是我的ItemsControl這是我的MainWindow.xaml。 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)); 
     } 
    } 
} 

如上所見,我更新基於CurrentIterationCurrentTime各種屬性。

也在MainWindow.xaml中看到上面的內容,我在單擊ItemsControl中的按鈕時調用一個命令。此命令位於我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設置在的ItemsSource的項目。我已驗證數據在那裏。

下面是時間線窗口中的.xaml:

<Window> 
    <Grid> 
     <TextBox IsReadOnly="True" 
       Text="{Binding CurrentYear, 
           Mode=OneWay}" /> 

     <TextBox IsReadOnly="True" 
       Text="{Binding CurrentDayOfYear, 
           Mode=OneWay}" /> 
    </Grid> 
</Window> 

當指定屬性的值發生變化,則不能正確在Timeline窗口的文本框更新。儘管據我所知,它們正在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; 
} 

上面應該依次更新CurrentIteration通知的其他屬性。

+0

'ShowTimeWindow'方法使得很難猜測發生了什麼。我的猜測是a)也許Timeline窗口對於DataContext具有'null',否則b)它具有與你在其他地方改變的'VehicleModel'不同的副本。如果我是你,我會希望'ShowTimeWindow'的實際參數是一個類實例,我在該方法的開始處施加一次,然後我將有命名和類型屬性來處理。 –

+0

因此,對於該方法的參數包含來自'ItemsControl'內被傳遞這三個變量如上所見: '<綁定路徑=「NowTime」 /> <綁定路徑=「名稱」 />' 所以它應該傳遞'NowTime'列表,datacontext和'Name'屬性。我檢查了'newTimeLine'的賦值,並且分配了datacontext。 – pfinferno

+0

所以你說要將'VehicleModel'實例本身作爲參數傳遞給'ShowTimeWindow'? – pfinferno

回答

1

VehicleViewModel.SetData()中的此行預計會更新CurrentTime,這會導致所有隻讀屬性「更新」,方法是爲每個屬性增加PropertyChanged

CurrentIteration = i; 

CurrentTime的制定者通吃的PropertyChanged通知。但你永遠不會打電話給那個製片人。 CurrentIteration二傳手只需撥打OnPropertyChanged("CurrentTime")

這裏有一個快速修復。如果是我,我可能會做下面的事情,或者我可能更傾向於使CurrentIteration明確設置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(); 
    } 
} 
+1

非常感謝!那樣做了。我正在爲此be首。 – pfinferno

相關問題