gpt4 book ai didi

wpf - 使用属性面板中的 TypeConverter 设置类类型的属性会生成扩展的 XAML,而不是字符串

转载 作者:行者123 更新时间:2023-12-03 10:02:59 24 4
gpt4 key购买 nike

我正在尝试使用类型是我定义的类的属性创建用户控件。我正在使用 TypeConverter允许将属性作为字符串处理。应用程序正确处理读取属性为字符串的 XAML,但如果通过属性面板将属性设置为字符串,则 XAML 包含扩展的语法,将用户定义的类分开。

具体来说,由于这有点难以理解,我正在关注 this Microsoft tutorial .结果我有以下代码:

复杂的.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>

如何确保生成的 XAML 简单地读取 ComplexNumber="1,-1" , 而不是冗长的 ComplexNumberControl.ComplexNumber构造?

最佳答案

你快到了,只需要对 进行两次小调整综合 类使其按预期工作:

1)删除默认的公共(public)构造函数:

public Complex() { } // <- delete this line

2) 添加神奇 DesignerSerializationVisibility 归属于 真实 属性(或一般来说 - 所有具有公共(public) setter 的属性):

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public double Real
{
get { return m_real; }
set { m_real = value; }
}

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public double Imaginary
{
get { return m_imag; }
set { m_imag = value; }
}

希望这可以帮助。

关于wpf - 使用属性面板中的 TypeConverter 设置类类型的属性会生成扩展的 XAML,而不是字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17064370/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com