当 ComboBox 不在绑定列表中时,防止将 selectedValue 设置为 null

Ala*_*ain 5 c# wpf xaml .net-4.0

我不太确定如何处理这个问题。我使用了一堆带有下拉值列表的组合框,我们也允许用户设置属性。(即货币=“美元、加元、欧元”)。

有时,当我们加载数据时,我们会发现该货币不在我们的列表中,例如“AUD”。在这种情况下,我们仍然希望组合框显示加载的值,并且当前选择的货币应保持“AUD”,除非用户选择更改它,在这种情况下,他们唯一的选项仍然是“USD、CAD、EUR”。

我的问题是,一旦控件变得可见,ComboBox 就会调用我的 SelectedCurrency 属性上的 setter 并将其设置为null,大概是因为当前值“AUD”不在其列表中。如何禁用此行为而不让用户可以在“货币”字段中输入他们想要的任何内容?

Phi*_*hil 1

这似乎是一个相当普遍的问题。想象一下,数据库中有一个查找列表,可能是员工列表。员工表有一个“在这里工作”标志。另一个表引用员工查找列表。当一个人离开公司时,你希望你的视图显示老员工的名字,但不允许老员工将来被分配。

这是我对类似货币问题的解决方案:

沙姆尔

<Page.DataContext>
    <Samples:ComboBoxWithObsoleteItemsViewModel/>
</Page.DataContext>
<Grid>
    <ComboBox Height="23" ItemsSource="{Binding Items}" 
              SelectedItem="{Binding SelectedItem}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

C#

// ViewModelBase and Set() are from MVVM Light Toolkit
public class ComboBoxWithObsoleteItemsViewModel : ViewModelBase
{
    private readonly string _originalCurrency;
    private ObservableCollection<string> _items;
    private readonly bool _removeOriginalWhenNotSelected;
    private string _selectedItem;

    public ComboBoxWithObsoleteItemsViewModel()
    {
        // This value might be passed in to the VM as a parameter
        // or obtained from a data service
        _originalCurrency = "AUD";

        // This list is hard-coded or obtained from your data service
        var collection = new ObservableCollection<string> {"USD", "CAD", "EUR"};

        // If the value to display isn't in the list, then add it
        if (!collection.Contains(_originalCurrency))
        {
            // Record the fact that we may need to remove this
            // value from the list later.
            _removeOriginalWhenNotSelected = true;
            collection.Add(_originalCurrency);
        }

        Items = collection;

        SelectedItem = _originalCurrency;
    }

    public string SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            // Remove the original value from the list if necessary
            if(_removeOriginalWhenNotSelected && value != _originalCurrency)
            {
                Items.Remove(_originalCurrency);
            }

            Set(()=>SelectedItem, ref _selectedItem, value);
        }
    }

    public ObservableCollection<string> Items
    {
        get { return _items; }
        private set { Set(()=>Items, ref _items, value); }
    }
}
Run Code Online (Sandbox Code Playgroud)