我有一个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;
}
}
答案 0 :(得分:1)
问题是你正在使用CollectionViewSource,它自动选择列表中的第一个元素,因为它无法找到&#34; null&#34;的条目。就个人而言,我认为在这种情况下使用CollectionViewSource是个好主意...你已经在Person.State中跟踪当前状态了,那你为什么需要一个CollectionViewSource来保持跟踪当前项目?如果你在同一页面上有两个ComboBox,会发生什么?您需要创建另一个CollectionViewSource,以便它们不会共享相同的索引。最后,任何涉及UI的逻辑(例如,管理当前选择的项目)都应该在视图模型中完成,以便可以对其进行测试。
您的代码存在一些需要修复的问题,首先是您将第一个ComboBox的SelectedValue绑定到Person.State。没有&#34; Person&#34;主视图模型的成员,我怀疑你的意思是NewPerson,对吗?其次,Person.State字段是一个字符串,但是你的ComboBox绑定到一个状态列表,所以当用户选择一个状态时,WPF将调用该状态的ToString()成员并将其设置为值,即你的Person。状态字段最终会出现像&#34; YourProjectName.State&#34;。您可以修复绑定来执行此操作,但更好的解决方案是将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");}
}
(请注意,您原来的城市成员存在问题......您已将其更改为CityId,但您正在On&#34; City&#34;)上进行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中构建你的数据......人真的是一个模型对象。
答案 1 :(得分:0)
您正在将SelectedIndex初始化为-1,但随后绑定了覆盖初始选择的SelectedValue。您有3个选择: