用户控件与 MVVM:两个取决于下限和上限值选择的组合框



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

(。

<示例>

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

  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,这可以正常工作。

    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
    

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

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

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

与其每次都创建一个新的上层集合,为什么不简单地使用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;
    }
}

XAML

<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>

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

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

最新更新