I am working with a form where some ComboBoxes can be created and removed programmatically.
When they are created, some triggers which target them are created and applied to a button:
Dictionary<ComboBox, DataTrigger> triggers = new Dictionary<ComboBox, DataTrigger>();
private void CreateTrigger(ComboBox box)
{
Style s = new Style(typeof(Button), MyButton.Style);
foreach(TriggerBase aTrigger in MyButton.Style.Triggers)
s.Triggers.Add(aTrigger);
DataTrigger t = new DataTrigger
{
Binding = new Binding("SelectedItem") { Source = box },
Value = null
};
t.Setters.Add(new Setter(Button.IsEnabledProperty, false));
s.Triggers.Add(t);
triggers.Add(box, t);
MyButton.Style = s;
}
So far so good*. . . the problem is, what to do when the ComboBox is removed from the window. I need to remove the trigger from the button’s Style, since I no longer want the ComboBox to influence its behavior. I tried the most obvious option:
private void RemoveTrigger(ComboBox box)
{
Style s = new Style(typeof(Button), MyButton.Style);
foreach(TriggerBase aTrigger in MyButton.Style)
if(aTrigger != triggers[box]) s.Triggers.Add(aTrigger);
triggers.Remove(box);
MyButton.Style = s;
}
But this does not seem to do the job – if the trigger is removed while it is active, then the button stays disabled.
I had assumed that the button would re-evaluate its Style whenever it is given a new one. that seems to be happening when the trigger is added, but not when it’s being removed – what am I missing here?
EDIT: Changed code for adding/removing triggers as per the advice in H.B.’s comment. However, the problem in question remains.
EDIT 2: *Maybe not so far so good after all – I went on to try adding an additional ComboBox (and trigger) and discovered that adding a second trigger seems to break the first one. Using this code, only the most recently added trigger works. Should I be perhaps thinking of a FrameworkElement’s triggers as a write-once collection and finding a different way to achieve this kind of behavior?
It’s been a long time since this question was asked, but I figured I’d at least post how I resolved the issue for the sake of sharing:
I never did find a way to remove triggers that worked reliably. So instead, I added a property to my View which indicated how all the triggers would have evaluated, if they had existed, and hooked a
DataTriggerup to this property.In place of adding and removing triggers, created an handlers to watch the properties that the triggers would have watched:
This sidesteps all the hassle with creating and removing triggers. Instead there’s one trigger, and adding and removing event handlers works just fine.
(Hacky, yes.)