WindowsStore ComboBox SelectedIndex未正确更新?

时间:2015-08-01 03:58:35

标签: wpf xaml mvvm combobox windows-store-apps

我有一个绑定到我的ViewModel的ComboBox。 SelectedIndex绑定到ViewModel上的属性。

我想要做的是,在某些条件下,索引上的某些选项变为无效,以便当用户尝试选择它时,它应显示错误消息< / strong>和不会更改当前选定的项目。

在后端,一切都很顺利。但是,在UI上,ComboBox的SelectedIndex仍然会更改。错误消息显示正确,但组合框中的“显示”选定项目不正确(例如,ComboBox当前为“项目4”,用户选择无效项目“项目3”,显示错误,但ComboBox仍显示'第3项')。

以下是XAML代码供参考:

<ComboBox x:Name="ComboBox_Cover"
                      HorizontalAlignment="Stretch"
                      ItemsSource="{Binding Path=Covers}"
                      SelectedIndex="{Binding Path=Cover,
                                              Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      Style="{StaticResource Style_ComboBox_CheckSelector}" />

我的ViewModel:

private int _Cover = 0;
    public int Cover
    {
        get { return _Cover; }
        set
        {
            bool canChangeCover = true;

            if(IfInvalid())
            {
                canChangeCover = false;
                ShowCoversError();

                RaisePropertyChanged("Cover");
            }

            if(canChangeCover)
            {
                _Cover = value;
                RaisePropertyChanged("Cover");
            }
        }
    }

我做错了吗?

我发现当前的解决方法是使用 OnSelectionChanged 事件,如果无效,则将SelectedIndex设置为正确的值。虽然我不确定这是否是一个好的解决方法。

谢谢!

1 个答案:

答案 0 :(得分:1)

最简单的方法是利用IsEnabled的{​​{1}}属性。只需修改ComboBoxItem绑定即可指向ItemsSource

列表

C#:

ComboBoxItem

XAML:

public class MainPageViewModel : INotifyPropertyChanged
{
    public MainPageViewModel()
    {
        Covers = new List<ComboBoxItem>
        {
            new ComboBoxItem { Content = "Item 1", IsEnabled = true },
            new ComboBoxItem { Content = "Item 2", IsEnabled = true },
            new ComboBoxItem { Content = "Item 3", IsEnabled = true },
            new ComboBoxItem { Content = "Item 4", IsEnabled = true }
        };
    }

    public List<ComboBoxItem> Covers { get; set; }

    private int selectedIndex;

    public int SelectedIndex
    {
        get { return selectedIndex; }
        set
        {
            if (SelectedIndex != value)
            {
                foreach (var cover in Covers)
                {
                    if (Covers.IndexOf(cover) < value)
                    {
                        cover.IsEnabled = false;
                    }
                }

                selectedIndex = value;
                NotifyPropertyChanged("SelectedIndex");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

如果您想在C#中保留数据模型的集合,可以实现<ComboBox HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{Binding Covers}" SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}" /> IValueConverter列表投影到Cover列表中。您还可以创建一个继承自ComboBoxItem的新类,并在需要将更多值绑定到控件模板时添加一些其他依赖项属性。例如,我玩弄了这个:

ComboBoxItem

值得注意的是,为了保持关注点的良好分离,我通常更喜欢将模型属性直接绑定到public class CoverComboBoxItem : ComboBoxItem { public string Description { get { return (string)GetValue(DescriptionProperty); } set { SetValue(DescriptionProperty, value); this.Content = value; } } public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(CoverComboBoxItem), new PropertyMetadata("")); } 的{​​{1}}属性。不幸的是,为了完成这项工作,您需要在IsEnabled内部设置绑定。不幸的是,声明绑定不受支持。我见过一些解决方法,但实现它们的复杂性远远超过我上面描述的解决方案。

希望有所帮助!