WPF创建通用的;选择工具";对于多个类
如果你把它简化成一个类,这个问题就相当容易了。给出下图,我想创建一个简单的双面控件,它根据布尔值将一个列表中的项目放入另一个列表中 编辑:您当然可以单击两个列表中的项目,然后该项目切换到另一个列表。此外,还会调用一个回调,以防我需要更新一些数据库内容 我创造了一张很好的照片来感动你,因为我被卡住了 世界并不像下面的例子那样简单:对于不同的类,您将如何解决这个问题。 想象一个像“Car”这样带有“IsFast”的类。或者像“水果”这样的带有“ILikeIt”的类。我不想每次都重新编程WPF控件,我需要一些方法来绑定。。。(哦,我想我刚刚有了一个想法)。。。但是,如果泛型类(比如T)实现了某些属性,那么还有什么好的做法可以允许它们呢。。还是包装类 我不知道,你会怎么解决它。使用OnClick函数的简单绑定似乎不够。。。不确定。。。顺便说一下,“编写3个控件”是一个合适的答案。如果更简单,就告诉我WPF创建通用的;选择工具";对于多个类,wpf,list,Wpf,List,如果你把它简化成一个类,这个问题就相当容易了。给出下图,我想创建一个简单的双面控件,它根据布尔值将一个列表中的项目放入另一个列表中 编辑:您当然可以单击两个列表中的项目,然后该项目切换到另一个列表。此外,还会调用一个回调,以防我需要更新一些数据库内容 我创造了一张很好的照片来感动你,因为我被卡住了 世界并不像下面的例子那样简单:对于不同的类,您将如何解决这个问题。 想象一个像“Car”这样带有“IsFast”的类。或者像“水果”这样的带有“ILikeIt”的类。我不想每次都重新编程WPF控件,我
创建一个用户控件。添加SourceList dep.属性。为回调添加委托属性,为“在列表中”筛选器添加委托属性 使用两个ListBox控件(左和右),用于设置两个列表的源,使用筛选器委托确定成员身份。我该怎么做
- 创建名为
的控件,该控件将PickList
子类化,并包含用于拾取单个项目、拾取所有项目、取消拾取所有项目等的命令ItemsControl
- 创建一个名为
的类,该类具有PickListItem
属性IsPicked
- 定义
的控制模板,以包括两个PickList
es和一组用于选择一个、所有等的按钮。该模板将包括两个ListBox
s,用于将拾取的项目(位于右侧)与未拾取的项目(位于左侧)分开CollectionViewSource
ItemsControl
一样使用此控件,并将其重新用于您可能拥有的任何数据类型:
<PickList ItemsSource="{Binding People}">
<PickList.ItemContainerStyle>
<Style TargetType="{x:Type PickListItem}">
<Setter Property="IsPicked" Value="{Binding IsRich}"/>
</Style>
</PickList.ItemContainerStyle>
</PickList>
我想我知道你在追求什么,这应该让你开始
我假设您的usercontrol有两个ListView,一个用于名为“TrueList”的真实项,另一个用于名为“FalseList”的虚假项
从ItemsCollection扩展usercontrol,并将每个listview的ItemsSource属性绑定到父usercontrol的ItemsSource
将TrueFilter和FalseFilter属性添加到usercontrol:
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;
}
}
最后,在事件回调上调用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”。好的,谢谢。。我认为关键字是**委托属性**,如果我取得显著进展,将对此进行研究并发表文章……您可以查看CollectionViewSource类,了解您的委托应该是什么样的。我认为这是一种方法。。我将按照您描述的方式实现它,并检查是否有任何不清楚的地方,然后带着反馈返回..PickListItem将从哪个类继承?DependencyObject,ContentControl,…?ContentControl-就像ListBoxItem,例如。好的,我正在尝试你的方法,因为它似乎是建议的方法,与WPF的设计工作方式最为一致。然而,我遇到了麻烦,任何关于如何实现其余部分的澄清或额外细节都会有所帮助。
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;
}
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;
}
}
public interface Valid
{
bool IsValid { get; set; }
}