我正在开发一个包含ComboBox的WPF用户控件。 ComboBox选项是时间单位,即秒,分钟,小时,天等,并通过数据库查找表提供。每个选项都与一个名为TimeInterval的枚举中可用的相应枚举值相关联。我们的应用程序的其他功能将根据所选的选项做出决定。
使用此控件的开发人员需要能够限制哪些时间单位可供选择。例如,在某些情况下,仅在列表中显示分钟和秒可能是合适的。其他开发人员可能希望提供整个列表。
我正试图想出一个优雅的方式来做这件事,但我不知所措。我的第一个想法是以某种方式在枚举上使用Flags(FlagsAttribute),但我不确定如何接近它。
纯XAML方法是理想的,但我也对代码解决方案持开放态度。
提前致谢。
答案 0 :(得分:1)
您可以使用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;
}
}
}
控制准备就绪,是时候使用它并限制一些项目了。在这个例子中,我阻止除“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;
}
}
}