2014-10-29 55 views
0

我有一個ComboBox綁定到一個CollectionViewSource,我希望默認情況下選定的索引應該是-1(因爲什麼都不應該被選中)我已經設置SelectedIndex =「 -1「 並且第一項仍處於選中狀態。爲什麼?組合框選定的索引-1綁定到集合查看源

我查看XAML:

<Window.Resources> 
    <CollectionViewSource x:Key="States" Source="{Binding States}"/> 
    <CollectionViewSource x:Key="Cities" Source="{Binding Source={StaticResource States}, Path=Cities}"/> 
</Window.Resources> 


      <ComboBox SelectedValue="{Binding Person.State}" Width="150" SelectedValuePath="StateInitial" DisplayMemberPath="StateName" ItemsSource="{Binding Source={StaticResource States}}"/> 
     <ComboBox SelectedValue="{Binding Person.City}" Width="150" SelectedValuePath="CityId" DisplayMemberPath="CityName" ItemsSource="{Binding Source={StaticResource Cities}}"/> 

型號C#

public class State 
{ 
    public State(string stateInitial, string stateName, ICollection<City> cities) 
    { 
     StateInitial = stateInitial; 
     StateName = stateName; 
     Cities = cities; 

    } 

    public string StateInitial { get; set; } 
    public string StateName { get; set; } 
    public virtual ICollection<City> Cities { get; set; } 



} 
public class City 
{ 
    public int CityId { get; set; } 
    public string CityName {get;set;} 


} 
public class Person : INotifyPropertyChanged 
{ 
    #region Fields 
    private string state; 
    private int city; 
    #endregion 

    public string State 
    { 
     get 
     { 
      return state; 
     } 
     set 
     { 
      state = value; 
      OnPropertyChanged("State"); 
     } 

    } 

    public int CityId 
    { 
     get 
     { 
      return city; 
     } 
     set 
     { 
      city = value; 
      OnPropertyChanged("City"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 

     } 
    } 


} 

視圖模型C#

public class MainWindowViewModel 
{ 
    public Person NewPerson { get; set; } 
    public List<State> States { get; private set; } 

    public MainWindowViewModel() 
    { 
     States = GetStates(); 
     NewPerson = new Person(); 
    } 
    public List<State> GetStates() 
    { 
     var stateList = new List<State>(); 
     var TaxesCities = new List<City>(); 
     TaxesCities.Add(new City(){ CityId = 1, CityName = "Dalles"}); 
     TaxesCities.Add(new City(){ CityId = 2, CityName = "Houstin"}); 
     stateList.Add(new State("TX", "Taxes" , TaxesCities)); 
     var NYCities = new List<City>(); 
     NYCities.Add(new City() { CityId = 3, CityName = "New York" }); 
     NYCities.Add(new City() { CityId = 4, CityName = "Brooklyn" }); 
     stateList.Add(new State("NY", "New York", NYCities)); 
     return stateList; 
    } 
} 

回答

1

問題是您使用的是CollectionViewSource,它自動選擇列表中的第一個元素,因爲它無法找到「null」條目。就我個人而言,我認爲在這種情況下使用CollectionViewSource並不是一個好主意......您已經在Person.State中跟蹤當前狀態,那麼爲什麼還需要一個CollectionViewSource來跟蹤當前項目?如果你在同一頁面上有兩個ComboBox,會發生什麼?您需要創建另一個CollectionViewSource,以便它們不共享同一個索引。最後,任何涉及UI的邏輯(例如,管理當前選定的項目)應該在視圖模型中完成,以便可以對其進行測試。

您的代碼有幾個問題需要修復,第一個問題是您首先綁定yoru ComboBox的SelectedValue到Person.State。沒有主視圖模型的「Person」成員,我懷疑你的意思是NewPerson,對嗎?其次,Person.State字段是一個字符串,但您的ComboBox綁定到狀態列表,所以當用戶選擇一個狀態時,WPF將調用該狀態的ToString()成員並將該值設置爲值,即您的Person.State字段將風與「YourProjectName.State」類似。您可以修復你的綁定要做到這一點,但更好的方法是修改Person類引用國家和城市直接:

private State state; 
    public State State 
    { 
     get {return state;} 
     set {state = value; OnPropertyChanged("State");} 

    } 

    private City city; 
    public City City 
    { 
     get {return city;} 
     set {city = value; OnPropertyChanged("City");} 
    } 

(注有在原來的城市部件問題......你會將其更改爲CityId,但您在「City」上進行了OnPropertyChanged)。

除了更好的性能方面,你不會有問題的組合框設置錯誤的初始狀態,如果你修復XAML綁定中的其他問題,你的主視圖現在也可以正常工作:

<ComboBox SelectedValue="{Binding NewPerson.State}" Width="150" DisplayMemberPath="StateName" ItemsSource="{Binding States}" /> 
    <ComboBox SelectedValue="{Binding NewPerson.City}" DisplayMemberPath="CityName" ItemsSource="{Binding NewPerson.State.Cities}" /> 

如果你真的想你的Person類利用國家名稱和城市的ID,那麼你應該創建一個保存參考,並執行轉換一個PersonViewModel。畢竟,這應該是如何在MVVM中構建數據的......人是一個真正的模型對象。

0

你初始化的SelectedIndex爲-1,但隨後綁定的SelectedValue被改寫初始選擇。您有3個選項:

  1. 擺脫SelectedIndex並將您的初始SelectedValue設置爲不在列表中的某個東西。
  2. 將SelectedIndex綁定到視圖模型中的整數,並在綁定建立後,在運行時將其設置爲-1。
  3. 保持原樣,但將您的SelectedValue的綁定模式設置爲OneWayToSource。這將阻止綁定覆蓋初始值,但如果您在視圖模型中創建SelectedIndex,它將不會反映對SelectedIndex的任何更改。
+0

謝謝你的迴應,但選項1和3似乎沒有工作選項2的作品,但我認爲它有點凌亂 – 2014-10-30 18:11:44

+0

奇怪,我測試了這兩種方法,並在.NET 4.5中,至少他們工作得很好。我猜別的東西是干擾綁定,發佈一個最小例子的任何機會? – 2014-10-30 21:57:31

+0

感謝您的回覆我編輯了問題添加了更多的代碼在我的情況下,我有一個動態數據列表,所以添加一個項目應該顯示「請選擇一個」不是一個選項 – 2014-11-04 21:44:41