[英]Combo Box Selected Index -1 bound to Collection View Source
我有一個ComboBox綁定到CollectionViewSource,並且我希望默認情況下所選索引應為-1(因為不應選擇任何內容),我已設置SelectedIndex =“-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));
}
}
}
ViewModel 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;
}
}
問題是您使用的是CollectionViewSource,它會自動選擇列表中的第一個元素,因為它找不到“ null”的條目。 我個人認為在這種情況下使用CollectionViewSource不是一個好主意...您已經在Person.State中跟蹤當前狀態,所以為什么還要使用CollectionViewSource來跟蹤當前項目? 如果在同一頁面上有兩個ComboBox,也會發生什么情況? 您需要創建另一個CollectionViewSource,以使它們不共享相同的索引。 最后,任何涉及UI的邏輯(例如,管理當前選定的項目)都應該在視圖模型中完成,以便可以對其進行測試。
您的代碼存在一些需要修復的問題,首先是您將第一個ComboBox的SelectedValue綁定到Person.State的事實。 主視圖模型中沒有“ Person”成員,我懷疑您是說NewPerson,對嗎? 其次,Person.State字段是一個字符串,但是您的ComboBox綁定到狀態列表,因此當用戶選擇一個狀態時,WPF將調用該狀態的ToString()成員並將其設置為該值,即您的Person.State字段將纏繞用“ YourProjectName.State”之類的東西。 您可以解決此問題,但是更好的解決方案是修改Person類以直接引用State和City:
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");}
}
(請注意,您原來的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中構造數據的方式……人實際上是一個模型對象。
您正在將SelectedIndex初始化為-1,然后綁定SelectedValue,這將覆蓋初始選擇。 您有3種選擇:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.