我正在尝试使用类型是我定义的类的属性创建用户控件。我正在使用 aTypeConverter
来允许将属性作为字符串处理。应用程序正确处理读取属性为字符串的 XAML,但如果通过属性面板将属性设置为字符串,则 XAML 包含扩展的语法,将用户定义的类分开。
具体来说,由于这有点难以理解,我正在关注这个 Microsoft 教程。结果我有以下代码:
复杂的.cs
namespace WpfApplication1
{
[TypeConverter(typeof(ComplexTypeConverter))]
public class Complex
{
private double m_real;
private double m_imag;
public Complex() { }
public Complex(double r, double i)
{
m_real = r;
m_imag = i;
}
public double Real
{
get { return m_real; }
set { m_real = value; }
}
public double Imaginary
{
get { return m_imag; }
set { m_imag = value; }
}
public override string ToString()
{
return String.Format("{0},{1}", this.m_real, this.m_imag);
}
public static Complex Parse(string complexNumber)
{
if (String.IsNullOrEmpty(complexNumber))
{
return new Complex();
}
// The parts array holds the real and
// imaginary parts of the object.
string[] parts = complexNumber.Split(',');
return new Complex(double.Parse(parts[0].Trim()), double.Parse(parts[1].Trim()));
}
}
public class ComplexTypeConverter : TypeConverter
{
private static List<Complex> defaultValues = new List<Complex>();
static ComplexTypeConverter()
{
defaultValues.Add(new Complex(0, 0));
defaultValues.Add(new Complex(1, 1));
defaultValues.Add(new Complex(-1, 1));
defaultValues.Add(new Complex(-1, -1));
defaultValues.Add(new Complex(1, -1));
}
// Override CanConvertFrom to return true for String-to-Complex conversions.
public override bool CanConvertFrom(
ITypeDescriptorContext context,
Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
// Override CanConvertTo to return true for Complex-to-String conversions.
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
// Override ConvertFrom to convert from a string to an instance of Complex.
public override object ConvertFrom(
ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value)
{
string text = value as string;
if (text != null)
return Complex.Parse(text);
return base.ConvertFrom(context, culture, value);
}
// Override ConvertTo to convert from an instance of Complex to string.
public override object ConvertTo(
ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value,
Type destinationType)
{
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
//Convert Complex to a string in a standard format.
Complex c = value as Complex;
if (c != null && this.CanConvertTo(context, destinationType))
{
return c.ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override TypeConverter.StandardValuesCollection GetStandardValues(
ITypeDescriptorContext context)
{
StandardValuesCollection svc = new StandardValuesCollection(defaultValues);
return svc;
}
}
}
ComplexNumberControl.xaml.cs
namespace WpfApplication1
{
public partial class ComplexNumberControl : UserControl
{
public ComplexNumberControl()
{
InitializeComponent();
}
public Complex ComplexNumber
{
get
{
return (Complex)this.GetValue(ComplexNumberProperty);
}
set
{
this.SetValue(ComplexNumberProperty, value);
}
}
public static readonly DependencyProperty ComplexNumberProperty = DependencyProperty.Register(
"ComplexNumber",
typeof(Complex),
typeof(ComplexNumberControl),
new PropertyMetadata(new Complex()));
}
}
主窗口.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:WpfApplication1">
<Grid>
<my:ComplexNumberControl HorizontalAlignment="Left" Margin="88,78,0,0" x:Name="complexNumberControl1" VerticalAlignment="Top" />
</Grid>
</Window>
我可以毫无错误地添加ComplexNumber="0,0"
(ComplexNumberControl
而且我知道,从更复杂的程序集中,该属性被正确处理为复数 0 + 0i)。但是,如果我ComplexNumber
在属性面板中进行编辑,XAML 将更改为:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:WpfApplication1">
<Grid>
<my:ComplexNumberControl HorizontalAlignment="Left" Margin="88,78,0,0" x:Name="complexNumberControl1" VerticalAlignment="Top">
<my:ComplexNumberControl.ComplexNumber>
<my:Complex Imaginary="-1" Real="1" />
</my:ComplexNumberControl.ComplexNumber>
</my:ComplexNumberControl>
</Grid>
</Window>
如何确保生成的 XAML 只是读取ComplexNumber="1,-1"
,而不是冗长的ComplexNumberControl.ComplexNumber
构造?