How does a MultiDataTrigger know when a Condition in its ConditionCollection is updated?
I'm trying to make a behavior had a ConditionCollection similar to MultiDataTrigger. I've looked through the reflected code, but I can't seem to follow how the MultiDataTrigger knows when to go through it's logic to determine if the conditions are met.
Here's the code:
[ContentProperty("Setters")]
public sealed class MultiDataTrigger : TriggerBase, IAddChild
{
// Fields
private ConditionCollection _conditions = new ConditionCollection();
private SetterBaseCollection _setters;
// Methods
internal override bool GetCurrentState(DependencyObject container, UncommonField<HybridDictionary[]> dataField)
{
bool flag = base.TriggerConditions.Length > 0;
for (int i = 0; flag && (i < base.TriggerConditions.Length); i++)
{
flag = base.TriggerConditions[i].ConvertAndMatch(StyleHelper.GetDataTriggerValue(dataField, container, base.TriggerConditions[i].Binding));
}
return flag;
}
internal override void Seal()
{
if (!base.IsSealed)
{
base.ProcessSettersCollection(this._setters);
if (this._conditions.Count > 0)
{
this._conditions.Seal(ValueLookupType.DataTrigger);
}
base.TriggerConditions = new TriggerCondition[this._conditions.Count];
for (int i = 0; i < base.TriggerConditions.Length; i++)
{
if ((this._conditions[i].SourceName != null) && (this._conditions[i].SourceName.Length > 0))
{
throw new InvalidOperationException(SR.Get("SourceNameNotSupportedForDataTriggers"));
}
base.TriggerConditions[i] = new TriggerCondition(this._conditions[i].Binding, LogicalOp.Equals, this._conditions[i].Value);
}
for (int j = 0; j < this.PropertyValues.Count; j++)
{
PropertyValue value2 = this.PropertyValues[j];
value2.Conditions = base.TriggerConditions;
switch (value2.ValueType)
{
case PropertyValueType.Trigger:
value2.ValueType = PropertyValueType.DataTrigger;
break;
case PropertyValueType.PropertyTriggerResource:
value2.ValueType = PropertyValueType.DataTriggerResource;
break;
default:
throw new InvalidOperationException(SR.Get(开发者_开发问答"UnexpectedValueTypeForDataTrigger", new object[] { value2.ValueType }));
}
this.PropertyValues[j] = value2;
}
base.Seal();
}
}
void IAddChild.AddChild(object value)
{
base.VerifyAccess();
this.Setters.Add(Trigger.CheckChildIsSetter(value));
}
void IAddChild.AddText(string text)
{
base.VerifyAccess();
XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this);
}
// Properties
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ConditionCollection Conditions
{
get
{
base.VerifyAccess();
return this._conditions;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public SetterBaseCollection Setters
{
get
{
base.VerifyAccess();
if (this._setters == null)
{
this._setters = new SetterBaseCollection();
}
return this._setters;
}
}
}
Basically, it doesn't. There is an internal StyleHelper class, which determines when to reevaluate the triggers. It does this based on the various bindings in the triggers.
Specifically, you can look at the StyleHelper. EvaluateOldNewStates method that takes a MultiDataTrigger.
精彩评论