在WPF ComboBox中设置默认值

5
我将使用ComboBox的ItemsSource属性绑定来显示一个List中的项到下拉框中。以下是代码:
<ComboBox x:Name="Cmb_Tax" ItemsSource="{Binding TaxList}" 
            DisplayMemberPath="ChargeName" SelectedItem="{Binding 
            SelectedTax,UpdateSourceTrigger=PropertyChanged}" IsEditable="True" 
            IsTextSearchEnabled="True" SelectionChanged="Cmb_Tax_SelectionChanged"/>

Classes.Charges _selected_tax = new Classes.Charges();
public Classes.Charges SelectedTax
{
    get
    {
        return _selected_tax;
    }
    set
    {
        _selected_tax = value;
    }
}

List<Classes.Charges> _taxlist = new List<Classes.Charges>();
public List<Classes.Charges> TaxList
{
    get
    {
        return _taxlist;
    }
    set
    {
        _taxlist = value;
        OnPropertyChanged("TaxList");
    }
}

它正确地显示了组合框中的项目。

TaxList中有一个特定的项目"无税",我希望在组合框中默认选择它。该项可以出现在列表的任何索引位置(不一定是列表的第一个或最后一个项目)。

我正在尝试使用以下代码设置组合框的选定索引属性,但遗憾的是它没有起作用。

TaxList = Classes.Charges.GetChargeList("Tax");
Cmb_Tax.DataContext = this;            
int i = TaxList.FindIndex(x => x.ChargeName == tax_name);
Cmb_Tax.SelectedIndex = i;

方法FindIndex()正确返回"No Tax"的索引,但当我尝试将其分配给组合框的SelectedIndex时,SelectedIndex没有改变。它仍然是-1。

更新1

private void Cmb_Tax_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    MessageBox.Show(SelectedTax.ChargeName);
}

更新2 根据@ElectricRouge建议更新了代码。

<ComboBox x:Name="Cmb_Tax" ItemsSource="{Binding TaxList, Mode=TwoWay}" 
                      DisplayMemberPath="ChargeName" SelectedItem="{Binding SelectedTax,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
                      IsEditable="True" IsTextSearchEnabled="True" 
                      SelectionChanged="Cmb_Tax_SelectionChanged"/>


Classes.Charges _selected_tax = new Classes.Charges();
        public Classes.Charges SelectedTax
        {
            get
            {
                return _selected_tax;
            }
            set
            {
                _selected_tax = value;
                OnPropertyChanged("SelectedTax");
            }
        }

        ObservableCollection<Classes.Charges> _taxlist = new ObservableCollection<Classes.Charges>();
        public ObservableCollection<Classes.Charges> TaxList
        {
            get
            {
                return _taxlist;
            }
            set
            {
                _taxlist = value;
                OnPropertyChanged("TaxList");
            }
        }

public void Load_Tax(string tax_name = null, Classes.Charges selected_tax = null)
        {
            TaxList = Classes.Charges.GetParticularChargeList("Tax");
            Cmb_Tax.DataContext = this;
            //Cmb_Tax.SelectedValue = tax_name;
            SelectedTax = selected_tax;
            //int i = TaxList.FindIndex(x => x.ChargeName == tax_name);
            //Cmb_Tax.SelectedIndex = i;
        }

有任何想法为什么会发生这种情况吗?同时,请建议其他方法在组合框中显示默认值。

1
我很好奇你的 Cmb_Tax_SelectionChanged 方法是做什么的。你能提供一下吗,这样我们就可以更好地理解问题? - deloreyk
你尝试设置SelectedTax成员(即你的SelectedItem绑定所指示的内容)而不是设置ComboBox的SelectedIndex了吗? - blins
尝试获取并将包含“无税”对象的SelectedTax分配给它,但仍然没有成功 :( - Nilesh Barai
我会考虑实现INotifyPropertyChanged并从setter中引发PropertyChanged事件。例如,它可能变成像这样的一行代码:SelectedTax = TaxList.FirstOrDefault(... - blins
2个回答

3

以下是一个可用的示例:

视图模型:

 public MainWindow()
    {
        InitializeComponent();

        var vm = new ViewModel();
        this.DataContext = vm;
        this.Loaded += (o,e) => vm.LoadData();
    }

    public class ViewModel : INotifyPropertyChanged
    {
        private IList<Charges> taxList;
        public ICollectionView TaxList { get; private set; }

        public void LoadData()
        {                
            taxList = Charges.GetChargeList("taxes");

            TaxList = CollectionViewSource.GetDefaultView(taxList);
            RaisePropertyChanged("TaxList");

            TaxList.CurrentChanged += TaxList_CurrentChanged;              

            var noTax = taxList.FirstOrDefault(c => c.ChargeName == "No Tax");
            TaxList.MoveCurrentTo(noTax);
        }

        void TaxList_CurrentChanged(object sender, EventArgs e)
        {
            var currentCharge = TaxList.CurrentItem as Charges;
            if(currentCharge != null)
                MessageBox.Show(currentCharge.ChargeName);
        }



        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

查看:

<ComboBox x:Name="cboTaxList" 
              ItemsSource="{Binding TaxList}" 
              DisplayMemberPath="ChargeName"
              IsSynchronizedWithCurrentItem="True" />

0
列表不实现 INotifyCollectionChanged,请将其改为ObservableCollection
ObservableCollection<Classes.Charges> _taxlist = new ObservableCollection<Classes.Charges>();
public ObservableCollection<Classes.Charges> TaxList
{
    get
    {
        return _taxlist;
    }
    set
    {
        _taxlist = value;
        OnPropertyChanged("TaxList");
    }
}

并尝试将Mode设置为TwoWay

SelectedItem="{Binding SelectedTax,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"

尝试了您的代码并尝试为SelectedTax赋值。组合框中没有选择任何值。 - Nilesh Barai
像这样:set { _selected_tax = value; OnPropertyChanged("SelectedTax"); } - ElectricRouge
我已经更新了帖子,并修改了代码。但仍然无法正常工作。 - Nilesh Barai
你是如何传递 DataContext 的? - ElectricRouge
在LoadTax()方法中 Cmb_Tax.DataContext = this; - Nilesh Barai
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接