我正在尝试为自定义DependencyProperty
创建Control
。
我希望能够设置一个FileList
属性,该属性将设置为字符串,以逗号分隔,但作为字符串列表存储在内存中。
这是我到目前为止所拥有的:
public class FileTypeListControl : Control
{
public static readonly DependencyProperty FileTypeListProperty
= DependencyProperty.Register(
"FileTypeList",
typeof(List<string>),
typeof(FileTypeListControl),
new PropertyMetadata(new List<string>() { ".txt" },
OnFileTypeListPropertyChanged,
OnCoerceFileTypeListProperty),
OnValidateFileTypeListPropety);
public List<string> FileTypeList
{
get
{
return (List<string>)GetValue(FileTypeListProperty);
}
set
{
SetValue(FileTypeListProperty, value);
}
}
public static void OnFileTypeListPropertyChanged(
DependencyObject source, DependencyPropertyChangedEventArgs e)
{
}
public static object OnCoerceFileTypeListProperty(
DependencyObject sender, object data)
{
if (data is string)
{
var val = (data as string).Split(new char[] { ',' });
return val;
}
else if (data is List<string>)
{
return data;
}
else
{
return new List<string>();
}
}
public static bool OnValidateFileTypeListPropety(object data)
{
return true;
}
}
<local:FileTypeListControl x:Name="control"
Grid.Column="2"
FileTypeList=".xml,.java,.exe"/>
现在,问题在于它不像我在xaml中指定FileTypeList
属性的方式。我的印象是OnCoerceFileListProperty
方法将值强制转换为合适的类型,这就是我正在做的事情。
我可以使用值转换器,但每次我想重新使用控件时,这都不正确。
我在这里做错了什么?
答案 0 :(得分:1)
CoerceValueCallback的目的不是执行类型转换。此任务通常由TypeConverters执行,如下所示:
public class StringListConverter : TypeConverter
{
public override bool CanConvertFrom(
ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(
ITypeDescriptorContext context, CultureInfo culture, object value)
{
return ((string)value).Split(',');
}
}
...
[TypeConverter(typeof(StringListConverter))]
public IList<string> FileTypeList
{
get { return (IList<string>)GetValue(FileTypeListProperty); }
set { SetValue(FileTypeListProperty, value); }
}
另请注意,将该属性声明为IList<string>
可提供比List<string>
更大的灵活性。
您还应该避免使用类似new List<string>() { ".txt" }
的表达式作为依赖项属性的默认值,因为此值用于属性的所有“实例”。当你例如在一个控件实例中向FileTypeList
属性添加一个字符串,只要它们具有默认属性值,此更改也将在其他控件实例中进行。
对于所有引用类型属性,默认值应为null
。然后,您可以在控件的构造函数中设置实际默认值:
public FileTypeListControl()
{
SetCurrentValue(FileTypeListProperty, new List<string>() { ".txt" });
}