I have some fun with WPF and I decided to build a library with custom implementation of attached triggers (similar to System.Windows.Interactivity.dll), but my own. I have a class TriggerAction
which represents an action invoked by Trigger. I want to begin with something really easy like setting the background of the button while the user click it. I have already written some working code for example EventTrigger class, but I have one problem with my SetterTriggerAction
. I have two dependency properties PropertyName
which represents the name of property which should be set an a Value
property. In the Invoke method I try to set property with a defined value. Here is the code:
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);
}
}
My second attempt:
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);
}
}
In xaml I wrote:
<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>
So when I click the button I want to make its background red. However both versions of Invoke method suffers from convertion issue and in my output window I get a message that "Red" is not valid value for property Background (because it is treated like string not a Brush!). Is there any way to convert a value from xaml (string "Red") to a valid Brush value? I would like to have as general way of converting properties as possible.
I consider that something similar to what I want to achieve is done when xaml is parsed and properties of controls are set.
Any help would be appreciated.
Aucun commentaire:
Enregistrer un commentaire