您可以利用 CollectionView 的优势来实现预期的行为。
在这种情况下,您的 UserControl 会公开 FilterTimeInterval 依赖属性,其类型为 Predicate<TimeInterval>。更改此属性时,您设置ICollectionView.Filter 属性以收集您的项目。如果第三方开发人员使用您的控件并希望限制组合框项目,他应该将适当的谓词绑定到 FilterTimeInterval 属性。
这里有一些演示(为了简化编码,combobox 包含字符串项)。
您的控件的 XAML:
<UserControl x:Class="Test.TimeIntervalsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ComboBox ItemsSource="{Binding Items}"/>
</Grid>
</UserControl>
带有依赖属性声明的控件背后的代码:
public partial class TimeIntervalsControl : UserControl
{
public TimeIntervalsControl()
{
InitializeComponent();
this.Model = new TimeIntervalsViewModel();
}
public TimeIntervalsViewModel Model
{
get
{
return (TimeIntervalsViewModel)this.DataContext;
}
set
{
this.DataContext = value;
}
}
public Predicate<string> FilterTimeInterval
{
get
{
return (Predicate<string>)this.GetValue(TimeIntervalsControl.FilterTimeIntervalProperty);
}
set
{
this.SetValue(TimeIntervalsControl.FilterTimeIntervalProperty, value);
}
}
public static readonly DependencyProperty FilterTimeIntervalProperty =
DependencyProperty.Register("FilterTimeInterval",
typeof(Predicate<string>),
typeof(TimeIntervalsControl),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None,
(d, e) =>
{
var control = (TimeIntervalsControl)d;
var view = CollectionViewSource.GetDefaultView(control.Model.Items);
if (e.NewValue == null)
{
view.Filter = null;
}
else
{
view.Filter = o => ((Predicate<string>)e.NewValue)((string)o);
}
}));
}
你的控件的ViewModel:
public sealed class TimeIntervalsViewModel : ObservableObject
{
private readonly string[] _items = new string[] {"Years","Month","Days","Hours","Minutes","Seconds"};
public IEnumerable<string> Items
{
get
{
return this._items;
}
}
}
控制已准备就绪,是时候使用它并限制一些项目了。在此示例中,我阻止了除“Days”之外的所有项目。
您在 XAML 中的控件用法如下所示:
<UserControl x:Class="Test.StartupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:self="clr-namespace:Test"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Root">
<WrapPanel>
<self:TimeIntervalsControl FilterTimeInterval="{Binding Path=DataContext.JustDaysFilter, ElementName=Root}"/>
</WrapPanel>
</UserControl>
当然我们应该在视图模型中准备 JustDaysFilter 属性:
public class StartupViewModel
{
private readonly Predicate<string> _justDaysFilter = s => s == "Days";
public Predicate<string> JustDaysFilter
{
get
{
return this._justDaysFilter;
}
}
}