我在线看到了两种不同的方法来增强IValueConverter。其中一个从MarkupExtension扩展了ValueConverter,另一个从DependencyObject扩展了。我无法从两方面延伸,所以我想知道是否有人比另一方好?改进的IValueConverter - MarkupExtension或DependencyObject?
回答
从每个派生给你别样的功能和灵活性:
从
MarkupExtension
派生使您可以使用值转换器,不使其成为一个静态资源,如下所述:public class DoubleMe : MarkupExtension, IValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(object value, /*rest of parameters*/) { if (value is int) return (int)(value) * 2; //double it else return value.ToString() + value.ToString(); } //... }
在XAML中,您可以在不创建StaticResource的情况下直接使用它:
<TextBlock Text="{Binding Name, Converter={local:DoubleMe}}"/> <TextBlock Text="{Binding Age, Converter={local:DoubleMe}}"/>
这样的代码在调试时非常方便,因为您只需编写
local:DebugMe
,然后调试您使用它的控件的DataContext。从
DependencyObject
派生使您能够配置值转换器更表达方式一些喜好,如下所述:public class TruncateMe : DependencyObject, IValueConverter { public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.Register("MaxLength", typeof(int), typeof(TruncateMe), new PropertyMetadata(100)); public int MaxLength { get { return (int) this.GetValue(MaxLengthProperty); } set { this.SetValue(MaxLengthProperty, value); } } public object Convert(object value, /*rest of parameters*/) { string s = value.ToString(); if (s.Length > MaxLength) return s.Substring(0, MaxLength) + "..."; else return s; } //... }
在XAML中,你可以直接使用它作为:
<TextBlock> <TextBlock.Text> <Binding Path="FullDescription"> <Binding.Converter> <local:TruncateMe MaxLength="50"/> </Binding.Converter> </Binding> </TextBlock.Text>
它有什么作用?如果它大于
50
个字符,它会截断字符串FullDescription
!
@crazyarabian评论说:
你的声明“派生自DependencyObject,可以配置以更表达方式的一些喜好值转换器”是不是独家的DependencyObject,你可以创建MarkupExtension上的相同MaxLength属性导致
<TextBlock Text="Binding Age, Converter={local:DoubleMe, MaxLength=50}}"/>
。我会争辩说一个MarkupExtension更具表现力且不那么冗长。
的确如此。但那是不可绑定的;也就是说,当你从MarkupExtension
派生,那么你可以这样做:
MaxLength="{Binding TextLength}"
但是如果你从DependencyObject
派生转换器,那么你可以做以上。从这个意义上说,它是更具表现力相比MarkupExtension
。
请注意,目标媒体资源必须为DependencyProperty
,Binding
才能使用。MSDN says,
每个结合通常具有这四种组分:一个结合靶 对象,目标属性,结合 源,并在 绑定源使用值的路径。例如,如果 要在 文本框的 Employee对象的名称属性的内容绑定,你的目标对象是 文本框,目标属性是 Text属性,使用的值是 名称,源对象是 员工对象。
目标属性必须是依赖项属性。
我在Codeplex上看到了Kent Boogaart的转换器项目,扩展了他从DependencyObject写的所有IValueConverter。 http://wpfconverters.codeplex.com/SourceControl/changeset/view/61942# – michael
@Nawaz您的声明“从DependencyObject派生”使您能够以更具表现力的方式为值转换器配置一些首选项“并非'DependencyObject',因为您可以在'MarkupExtension'上创建相同的'MaxLength'属性,从而生成'
@crazyarabian:是的。你可以做到这一点,但那是不可绑定的。你不能'MaxLength =“{绑定TextLength}”'。 – Nawaz
因为它是my library你引用的扩展DependencyObject
转换器的一个例子,我觉得这件解释自己。
我实际上是通过简单地将IValueConverter
与Object
作为我的基类来开始的。我转向扩展DependencyObject
的唯一原因是为了允许由Josh Smith开创的技术 - 称为虚拟分支。你可以阅读关于该技术here。
假设你想要做这样的事情:
<UserControl.Resources>
<con:CaseConverter Casing="{Binding SomeProperty}"/>
</UserControl.Resources>
这是行不通的,因为资源是不可视树的一部分,那么绑定操作将失败。虚拟分支绕过这个小小的困境,使您能够执行这样的绑定。但是,它仍然依赖 - 像任何其他WPF绑定 - 对目标是DependencyObject
。因此,如果我只是在不扩展DependencyObject
的情况下实施IValueConverter
,那么您将无法使用虚拟分支机构。
现在,如果我是完全诚实的,我不确定如果我再次度过我的时间,我仍然会这样做。我从来没有真的有自己使用虚拟分支 - 我只是想启用该场景。我甚至可以在我的图书馆的未来版本中更改它。所以我的建议是坚持基类Object
(或其简单的衍生物),除非你真的认为你需要虚拟分支。
这也可以在Silverlight中使用吗? – Shimmy
- 1. 的Silverlight的MarkupExtension
- 2. MarkupExtension中的DepedencyProperty
- 3. 更改DependencyProperites时调用DependencyObject的绑定
- 4. x:Silverlight中的Shared MarkupExtension
- 5. 使用IValueConverter和DynamicResource?
- 6. LongListSelector带有Itemtemplate或IValueConverter的严重Bug
- 7. 来自字符串的IValueConverter
- 8. ValidationRule和DependencyObject
- 9. Xamarin.Forms.Xaml.XamlParseException:找不到MarkupExtension
- 10. 获取价值的MarkupExtension
- 11. 用的MarkupExtension绑定参数
- 12. Silverlight5的MarkupExtension在设计时
- 13. Resourcealm中的IValueConverter
- 14. DependencyObject Array C#VB.NET
- 15. 具有绑定相关属性的IValueConverter
- 16. 实现DependencyObject和INotifyPropertyChanged
- 17. 默认IValueConverter
- 18. 的IValueConverter visibility属性
- 19. DiggSpy的改进或变化
- 20. 对DependencyObject和DependencyProperty的依赖
- 21. DependencyObject的绑定上下文
- 22. 列出DependencyObject的属性?
- 23. 读取附在非DependencyObject的
- 24. WPF - 通用IValueConverter?
- 25. WPF Ivalueconverter空值
- 26. WPF:单向IValueConverter
- 27. IValueConverter问题
- 28. 我应该使用的IValueConverter
- 29. ObservableCollection的Visibility IValueConverter <T>
- 30. 用于收集的IValueConverter
我想这取决于你想达到的目标。你可以添加更多的细节? –