我有一个绑定到我的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设置为正确的值。虽然我不确定这是否是一个好的解决方法。
谢谢!
答案 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
内部设置绑定。不幸的是,声明绑定不受支持。我见过一些解决方法,但实现它们的复杂性远远超过我上面描述的解决方案。
希望有所帮助!