Вы можете использовать преимущества CollectionView для достижения ожидаемого поведения.
В этом случае ваш UserControl предоставляет свойство зависимостей FilterTimeInterval, тип которого Predicate<TimeInterval>
. Когда это свойство изменяется, вы устанавливаете ICollectionView.Filter
свойство для сбора ваших предметов. Если сторонний разработчик использует ваш элемент управления и хочет ограничить элементы комбинированного списка, он должен просто связать соответствующий предикат со свойством FilterTimeInterval.
Вот некоторая демонстрация (чтобы упростить кодирование, комбинированный список содержит строковые элементы).
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;
}
}
}
Управление готово, пришло время использовать его и ограничить некоторые элементы. В этом примере я блокирую каждый элемент, кроме «Дней».
Использование вашего элемента управления в 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;
}
}
}