Я думаю Я понимаю, что вы после этого, это должно начать вас.
Я предполагаю, что ваш usercontrol имеет два списка просмотра, один из которых предназначен для true элементов с именем "TrueList", другой для false элементов с именем "FalseList".
Расширьте свой usercontrol из ItemsCollection и свяжите свойство ItemsSource каждого просмотра списка с ItemsSource родительского usercontrol.
Добавьте свойство TrueFilter и FalseFilter в свой пользовательский контроль:
Predicate<object> trueFilter;
public Predicate<object> TrueFilter
{
get
{
return trueFilter;
}
set
{
if (trueFilter!= null && this.TrueList.Items != null)
this.TrueList.Items.Filter -= trueFilter;
trueFilter = value;
if (trueFilter!= null && this.TrueList.Items != null)
this.TrueList.Items.Filter += trueFilter;
}
}
Predicate<object> falseFilter;
public Predicate<object> FalseFilter
{
get
{
return falseFilter;
}
set
{
if (falseFilter!= null && this.FalseList.Items != null)
this.FalseList.Items.Filter -= falseFilter;
filter = value;
if (falseFilter!= null && this.FalseList.Items != null)
this.FalseList.Items.Filter += falseFilter;
}
}
Затем создайте интерфейс «IToggle» (или другое более значимое имя):
public interface IToggle
{
Predicate<object> TrueFilter { get; }
Predicate<object> FalseFilter { get; }
}
Затем расширьте ObservableCollection для каждого из ваших пользовательских классов, реализуя интерфейс "IToggle":
public class Cars : ObservableCollection<Car>, IToggle
{
Predicate<object> trueFilter;
public Predicate<object> TrueFilter
{
get
{
if (trueFilter == null)
trueFilter = new Predicate<object>(this.TrueFilterPredicate);
return trueFilter;
}
}
private bool TrueFilterPredicate(object value)
{
Car car = (Car)value;
return car.IsFast;
}
Predicate<object> falseFilter;
public Predicate<object> FalseFilter
{
get
{
if (falseFilter == null)
falseFilter = new Predicate<object>(this.FalseFilterPredicate);
return falseFilter;
}
}
private bool FalseFilterPredicate(object value)
{
Car car = (Car)value;
return !car.IsFast;
}
Далее переопределите свойство ItemsSource в своем пользовательском элементе управления:
public new IEnumerable ItemsSource
{
get { return base.ItemsSource; }
set
{
if (value != null && !(value is IToggle))
throw new Exception("You may only bind this control to collections that implement IToggle.");
base.ItemsSource = value;
this.TrueFilter = base.ItemsSource == null ? null : (base.ItemsSource as IToggle).TrueFilter;
this.FalseFilter = base.ItemsSource == null ? null : (base.ItemsSource as IToggle).FalseFilter;
}
}
Наконец, вызовите TrueList.Items.Refresh () и FalseList.Items.Refresh () для ваших обратных вызовов событий, чтобы обновить представления элементов всякий раз, когда вы переключаете элемент с true на false, и наоборот.
Это решение все еще требует написания некоторого кода реализации для каждого пользовательского класса (фильтры true и false), но оно должно сводить дополнительный код к минимуму.
В качестве альтернативы было бы гораздо более простое решение, если бы вы дали каждому из ваших пользовательских классов общий интерфейс, что-то вроде:
public interface Valid
{
bool IsValid { get; set; }
}
Тогда вы могли бы использовать один набор фильтров (или наборы стилей, или привязку данных с конвертерами) для работы с «Действительным» интерфейсом. Вместо «Car.IsFast» и «Fruit.ILikeIt» вы должны использовать «Car.IsValid» и «Fruit.IsValid».