У меня есть некоторое удовольствие с WPF, и я решил создать библиотеку с пользовательской реализацией подключенных триггеров (аналогично System.Windows.Interactivity.dll), но моя.Set DependencyProperty от отражения в преобразовании типа wpf
У меня есть класс TriggerAction
, который представляет действие, вызываемое триггером. Я хочу начать с чего-то очень легкого, как установка фона кнопки, когда пользователь нажимает на нее.
Я уже написал некоторый рабочий код, например, класс EventTrigger, но у меня есть одна проблема с моим SetterTriggerAction
. У меня есть два свойства зависимостей PropertyName
, который представляет собой название свойства, которое должно быть установлено как Value
. В методе Invoke я пытаюсь установить свойство с определенным значением.
Вот код:
internal override void Invoke(DependencyObject obj)
{
if (obj == null)
return;
if (string.IsNullOrEmpty(PropertyName))
return;
PropertyInfo property = obj.GetType().GetProperty(PropertyName, BindingFlags.Public | BindingFlags.Instance);
if (property == null)
{
Debug.WriteLine("Cannot find property {0} for type {1}.", PropertyName, obj.GetType());
return;
}
MethodInfo setMethod = property.GetSetMethod();
if (setMethod == null)
{
Debug.WriteLine("The property {0} does not have set method.", PropertyName);
return;
}
try
{
setMethod.Invoke(obj, new object[] { Value });
}
catch(Exception ex)
{
Debug.WriteLine("Exception caught {0} with message {1}", ex.GetType(), ex.Message);
}
}
Моя вторая попытка:
internal override void Invoke(DependencyObject obj)
{
if (obj == null)
return;
if (string.IsNullOrEmpty(PropertyName)) return;
FieldInfo property = obj.GetType().GetField(PropertyName+"Property", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
if (property == null)
{
Debug.WriteLine("Cannot find dependency property {0} for type {1}.", PropertyName+"Property", obj.GetType());
return;
}
try
{
DependencyProperty dp = property.GetValue(obj) as DependencyProperty;
if(dp == null)
{
Debug.WriteLine("Cannot get DependencyProperty {0}", PropertyName + "Property");
return;
}
obj.SetValue(dp, Value);
}
catch(Exception ex)
{
Debug.WriteLine("Exception caught {0} with message {1}", ex.GetType(), ex.Message);
}
}
В XAML я писал:
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="Click">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:SetterTriggerAction PropertyName="Background" Value="Red"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Так что, когда я нажимаю кнопку, я хочу внести свой фон красный. Однако обе версии метода Invoke страдают от проблемы с конверсией, и в моем окне вывода появляется сообщение о том, что «Red» недопустимо для свойства Background (потому что он обрабатывается как строка, а не кисть!). Есть ли способ конвертировать значение из xaml (строка «Красный») в действительное значение Brush? Я хотел бы иметь как можно более общий способ преобразования свойств.
Я считаю, что что-то похожее на то, что я хочу достичь, выполняется при анализе xaml и задаются свойства элементов управления.
Любая помощь будет оценена по достоинству.
Я уже справиться с этой проблемой. Решение состоит в том, чтобы получить тип свойства и проверить, помечен ли он TypeConverterAttribute. Затем динамически создайте экземпляр конвертера и вызовите метод ConvertFrom. В сборке «PresentationCore» имеется много классов «TypeConverter» – bakala12