我有一个使用绑定转换器的UserControl。我把转换器变成了
的内部类public partial class MyPanel : UserControl
{
public class CornerRadiusConverter : IValueConverter
{
如何从XAML引用Converter类?以下不起作用:
<controls:MyPanel.CornerRadiusConverter x:Key="CornerRadiusConverter" />
它给出了这个错误:
标签 'LensPanel.CornerRadiusConverter'确实如此 XML名称空间中不存在 'CLR-名称空间:MyApp.Windows.Controls'
答案 0 :(得分:2)
有可能。几个月前,我写了一个标记扩展来为你内联创建转换器。它保留弱引用的字典,以便您不创建同一转换器的多个实例。处理创建具有不同参数的转换器。
在XAML中:
<TextBox Text="{Binding Converter={NamespaceForMarkupExt:InlineConverter {x:Type NamespaceForConverter:ConverterType}}}"/>
C#:
[MarkupExtensionReturnType(typeof(IValueConverter))]
public class InlineConverterExtension : MarkupExtension
{
static Dictionary<string, WeakReference> s_WeakReferenceLookup;
Type m_ConverterType;
object[] m_Arguments;
static InlineConverterExtension()
{
s_WeakReferenceLookup = new Dictionary<string, WeakReference>();
}
public InlineConverterExtension()
{
}
public InlineConverterExtension(Type converterType)
{
m_ConverterType = converterType;
}
/// <summary>
/// The type of the converter to create
/// </summary>
/// <value>The type of the converter.</value>
public Type ConverterType
{
get { return m_ConverterType; }
set { m_ConverterType = value; }
}
/// <summary>
/// The optional arguments for the converter's constructor.
/// </summary>
/// <value>The argumments.</value>
public object[] Arguments
{
get { return m_Arguments; }
set { m_Arguments = value; }
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
PropertyInfo propertyInfo = target.TargetProperty as PropertyInfo;
if (!propertyInfo.PropertyType.IsAssignableFrom(typeof(IValueConverter)))
throw new NotSupportedException("Property '" + propertyInfo.Name + "' is not assignable from IValueConverter.");
System.Diagnostics.Debug.Assert(m_ConverterType != null, "ConverterType is has not been set, ConverterType{x:Type converterType}");
try
{
string key = m_ConverterType.ToString();
if (m_Arguments != null)
{
List<string> args = new List<string>();
foreach (object obj in m_Arguments)
args.Add(obj.ToString());
key = String.Concat(key, "_", String.Join("|", args.ToArray()));
}
WeakReference wr = null;
if (s_WeakReferenceLookup.TryGetValue(key, out wr))
{
if (wr.IsAlive)
return wr.Target;
else
s_WeakReferenceLookup.Remove(key);
}
object converter = (m_Arguments == null) ? Activator.CreateInstance(m_ConverterType) : Activator.CreateInstance(m_ConverterType, m_Arguments);
s_WeakReferenceLookup.Add(key, new WeakReference(converter));
return converter;
}
catch(MissingMethodException)
{
// constructor for the converter does not exist!
throw;
}
}
}
答案 1 :(得分:2)
我再次考虑这个问题,我想出了类似于Dennis解决方案的东西:创建一个带有Type属性的“代理”转换器类,它将创建实际转换器的实例并将转换委托给它
public class Converter : IValueConverter
{
private Type _type = null;
public Type Type
{
get { return _type; }
set
{
if (value != _type)
{
if (value.GetInterface("IValueConverter") != null)
{
_type = value;
_converter = null;
}
else
{
throw new ArgumentException(
string.Format("Type {0} doesn't implement IValueConverter", value.FullName),
"value");
}
}
}
}
private IValueConverter _converter = null;
private void CreateConverter()
{
if (_converter == null)
{
if (_type != null)
{
_converter = Activator.CreateInstance(_type) as IValueConverter;
}
else
{
throw new InvalidOperationException("Converter type is not defined");
}
}
}
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
CreateConverter();
return _converter.Convert(value, targetType, parameter, culture);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
CreateConverter();
return _converter.ConvertBack(value, targetType, parameter, culture);
}
#endregion
}
你这样使用它:
<Window.Resources>
<my:Converter x:Key="CornerRadiusConverter" Type="{x:Type controls:MyPanel+CornerRadiusConverter}"/>
</Window.Resources>
答案 2 :(得分:-3)
我的工作是:
<Window.Resources>
<ResourceDictionary>
<Converters:BooleanNotConverter x:Key="BooleanNotConverter"/>
</ResourceDictionary>
</Window.Resources>
然后在控件中
<CheckBox IsChecked="{Binding Path=BoolProperty, Converter={StaticResource BooleanNotConverter} />