タイプが定義したクラスであるプロパティを持つユーザー コントロールを作成しようとしています。TypeConverter
プロパティを文字列として処理できるようにするためにa を使用しています。アプリケーションは、プロパティが文字列の XAML の読み取りを正しく処理しますが、プロパティ パネルでプロパティが文字列に設定されている場合、XAML にはユーザー定義クラスを分割する拡張構文が含まれます。
具体的には、ちょっとわかりにくかったので、このマイクロソフトのチュートリアルに従っています。結果として、次のコードがあります。
Complex.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()));
}
}
MainWindow.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>
ComplexNumber="1,-1"
生成された XAMLが、詳細な構造体ではなく、単純に読み取るようにするにはどうすればよいComplexNumberControl.ComplexNumber
ですか?