1

假设我有两个组合框。一个用于较低值,一个用于较高值。用户必须选择这两个值。为了让她感到舒服,我想通过限制上限组合框中的值来防止错误(下限>上限)。

<示例>

这里举个例子。(在示例中,我使用整数 - 我的现实世界问题有不同的对象。)

  1. 用户可以在 [1..5] 范围内进行选择:

    lower: [1, 2, 3, 4, 5]  --> no lower-value selected
    upper: [1, 2, 3, 4, 5]  --> no upper-value selected
    
  2. 如果她选择 3 作为下限值,我希望上复选框仅提供值 [3..5]。通过更改上部组合框的数据绑定 ObservableCollection<MyObj> 可以正常工作。

    lower: [1, 2, __3__, 4, 5]  --> User has selected '3'
    upper: [3, 4, 5]            --> after that, only values within the range [3..5] are available.
    
  3. 用户选择 4 作为上限值

    lower: [1, 2, __3__, 4, 5]  --> User has selected '3'
    upper: [3, __4__, 5]        --> User has selected '4'
    
  4. 用户改变主意并选择 2 作为较低的值

    lower: [1, __2__, 3, 4, 5]  --> User has selected '2'
    upper: [2, 3, __4__, 5]     --> '4' should be kept selected
    

</示例>

在 windows 窗体世界中,我会创建一个用户控件并自己控制事件处理。事实上,我会关闭SelectedIndexChanged上组合框的事件处理,调整它的底层列表,设置适当的索引并再次打开事件处理。

我在第四步遇到了一个奇怪的问题。我发现在更改基础集合时无法保留所选值。

  • 处理此类问题的 mvvm 方式是什么?还是 mvvm 模式不是适合我的方案的良药?
  • 这是一个用户控件的正确位置,我可以完全控制事件处理吗?
  • Expression-Blend 真的是使用 mvvm 模式构建的吗?;-)
4

2 回答 2

2

而不是每次都创建一个新的上层集合,为什么不简单地使用 ICollectionView.Filter 呢?这样您就可以保留所选项目。

编辑:快速而肮脏的例子;)

public class MyCbo
{
    private int _selectedInt;
    public int SelectedInt
    {
        get { return _selectedInt; }
        set { _selectedInt = value; 
        this.view.Refresh();}
    }

    public List<int> MyFirst { get; set; }
    public List<int> MySecond { get; set; }

    private ICollectionView view;

    public MyCbo()
    {
        this.MyFirst = new List<int>() {1, 2, 3, 4, 5};
        this.MySecond = new List<int>() { 1, 2, 3, 4, 5 };

        this.view = CollectionViewSource.GetDefaultView(this.MySecond);
        this.view.Filter = Myfilter;
    }

    private bool Myfilter(object obj)
    {
        var item = Convert.ToInt32(obj);

        var upper = this.SelectedInt;

        if (item < upper)
            return false;

        return true;
    }
}

用户控制

public partial class Comboxtwo : UserControl
{
    private MyCbo data;
    public Comboxtwo()
    {
        this.data = new MyCbo();
        InitializeComponent();
        this.DataContext = data;
    }
}

xml

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition  />
    </Grid.ColumnDefinitions>
    <ComboBox Grid.Column="0" ItemsSource="{Binding MyFirst}" SelectedItem="{Binding SelectedInt, Mode=OneWayToSource}" Height="30"/>
    <ComboBox Grid.Column="1" ItemsSource="{Binding MySecond}" Height="30" />
</Grid>
于 2012-05-04T13:29:29.773 回答
-1

只是给你一个工作方向的推动力:这听起来像是你可以用BindableLinq解决的问题,这将使你保持对 MVVM 的忠诚,并在你需要时保持灵活性。

如果您需要更多详细信息,请发表评论。

于 2012-05-04T13:27:06.700 回答