2014-01-14 34 views
0

當試圖通過XAMLListView綁定到ObservableCollection時,ListView未更新,並且最初使用空值加載。WPF數據綁定不能通過XAML工作(僅通過代碼)

通過XAML

History.xaml.cs

DataContext = this; 

History.xaml:

<ListView x:Name="lvHistory" ItemsSource="{Binding Source=history}" BorderThickness="0" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="2" util:GridViewSort.AutoSort="True" SizeChanged="lvHistory_SizeChanged"> 

通過代碼

當操作的方式從代碼的結合,該綁定工作正常。

History.xaml

<ListView x:Name="lvHistory" BorderThickness="0" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="2" util:GridViewSort.AutoSort="True" SizeChanged="lvHistory_SizeChanged"> 

History.xaml.cs

DataContext = this; 
lvHistory.ItemsSource = history; 

只需通過代碼添加的ItemsSource和XAML刪除它,代碼工作正常。我錯過了什麼?我如何通過純XAML創建綁定?

歷史:

public ObservableCollection<LocateElement> history { get; private set; } 

代碼更新列表:

public void Update() 
    { 
     if (updater.IsBusy) updatePending = true; 
     else 
     { 
      searchValue = txtSearch.Text.Trim(); 
      updatePending = false; 
      updater.RunWorkerAsync(); 
     } 
    } 

    private void updateContent(object sender, DoWorkEventArgs e) 
    { 
     try 
     { 
      Globals.Variables.logger.Info("Locate History: Updating"); 

      using (var db = new Data.DataManager()) 
      { 
       var history = db.LocateHistory.Where(o => o.ReceivedBy == Globals.Variables.loginDetails.UserID); 

       e.Result = filterResults(history); 
      } 

     } 
     catch (Exception er) 
     { 
      Globals.Variables.logger.Error(er); 
     } 
    } 

    private void updateFinished(object sender, RunWorkerCompletedEventArgs e) 
    { 
     List<LocateElement> r = (List<LocateElement>)e.Result; 

     history.Clear(); 
     foreach (LocateElement l in r) 
     { 
      history.Add(l); 
     } 

     if (updatePending) Update(); 
     //else Wpf.Util.GridViewSort.ReapplySort(lvHistory); 
    } 

    private List<LocateElement> filterResults(IQueryable<LocateElement> list) 
    { 
     List<LocateElement> history = new List<LocateElement>(); 

     foreach (LocateElement l in list) 
     { 
      if (searchValue != "") 
      { 
       // Use the parameters to filter the results. 
       Regex reg = new Regex(WildcardToRegex(searchValue)); 


       if (reg.IsMatch(l.Serial) || reg.IsMatch(l.Asset) || reg.IsMatch(l.DeviceType) || reg.IsMatch(l.Company) || (l.ReceivedFrom != null && reg.IsMatch(l.ReceivedFrom.Name)) || (l.ReceivedTo != null && reg.IsMatch(l.ReceivedTo.Name)) || reg.IsMatch(l.Row) || reg.IsMatch(l.Shelf) || reg.IsMatch(l.Bin) || reg.IsMatch(l.DateReceived.ToString())) 
       { 
        history.Add(l); 
       } 
      } 
      else 
      { 
       history.Add(l); 
      } 
     } 

     return history; 
    } 

回答

1

一個BindingSource財產並不意味着你認爲這意味着什麼。改爲使用Path,或讓它假定您正在談論Path(默認)。這應該做到這一點。

<ListView ItemsSource="{Binding history}" ...> 

此外,如果你是設置你的構造外history屬性,它需要通知的屬性已更改。如果你只是在你的構造函數中設置它,你不需要,但是你可能想讓它支持readonly而不是自動獲取器/設置器。 (TrueEddie的解決方案描述了這個問題並提供瞭解決方案,以便將實際變量換出)。

+0

設置'ItemsSource =「{綁定歷史}」'工作。值已正確更新,無需添加通知。 – teynon

+0

正如@McAden所解釋的那樣,您可能會看到像這樣寫成的綁定「ItemsSource =」{Binding Path = history}'。 – deloreyk

2

當你將數據傳輸到歷史收集你需要確保你提升屬性更改事件。

例如:

public class MyViewModel : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     private ObservableCollection<LocateElement> _history; 

     public ObservableCollection<LocateElement> history 
     { 
      get { return _history; } 
      set 
      { 
       if (_history != value) 
       { 
        _history = value; 

        RaisePropertyChanged("history"); 
       } 
      } 
     } 

     public MyViewModel() 
     { 
      _history = new ObservableCollection<LocateElement>(); 
     } 

     private void RaisePropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
+0

根據http://msdn.microsoft.com/zh-cn/library/ms668604(v=vs.110).aspx,「表示動態數據集合,它在項目添加,刪除或何時提供通知整個列表都會刷新。「這對我來說也沒有意義,因爲代碼工作正常。它只有當我通過xaml而不是代碼進行綁定時纔會更新。 – teynon

+0

這是正確的。但是當您替換對象時它不會通知您。因此,如果您將歷史記錄分配給對象A,則需要通知UI歷史記錄已更改。之後,對象A的添加/刪除/刷新將自動通知用戶界面。 – TrueEddie

+0

@TueEddie - 如果他正在改變構造函數之外的歷史屬性,那麼你是正確的。在提供的代碼中沒有證據表明這一點(儘管我承認重複使用具有相同名稱的局部變量有點令人困惑) – McAden