簡體   English   中英

組合框選定索引-1綁定到收藏集

[英]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種選擇:

  1. 擺脫SelectedIndex並將您的初始SelectedValue設置為列表中未包含的值。
  2. 在綁定建立后,將SelectedIndex綁定到視圖模型中的整數,並在運行時將其設置為-1。
  3. 保持原樣,但將SelectedValue的綁定模式設置為OneWayToSource。 這將防止綁定覆蓋初始值,但是如果您在視圖模型中進行更改,它將不會反映對SelectedIndex的任何更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM