The correct way to remove a trigger

I work with a form where some ComboBox can be created and deleted programmatically.

When they are created, some triggers that target them are created and applied to the 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 Style button, since I no longer want the ComboBox to affect 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 is not like completing a task - if the trigger is deleted when it is active, the button remains disabled.

I suggested that the button will re-evaluate its style whenever it is given a new one. what seems to happen when a trigger is added, but not when it is removed - what am I missing here?

EDIT: Changed the code for adding / removing triggers as recommended in the HB comment . However, this problem remains.

EDIT 2: * Perhaps this is not so good so far - I continued trying to add an extra ComboBox (and trigger) and found that adding a second trigger seems to break the first one. Using this code, only the last added trigger works. Should I perhaps think that FrameworkElement triggers are a write-once collection and find another way to achieve this behavior?

+6
source share
2 answers

It has been a long time since this question was asked, but I decided that I would at least publish how I solved the problem for the sake of sharing:

I never found a way to remove triggers that worked reliably. So instead, I added a property to my view, which indicated how all the triggers would be evaluated if they existed, and connected the DataTrigger to this property.

 public bool TriggerPoseur { get; set; } // Actually notifies when it changes 

Instead of adding and removing triggers, create handlers to view the properties that triggers will observe:

 public void ComboBoxDataContext_SelectedItemChanged(object sender, PropertyChangedEventArgs e) { //update TriggerPoseur } 

This reduces the complexity of creating and deleting triggers. Instead, a single trigger, as well as adding and removing event handlers works fine.

(Hakki, yes.)

+1
source

So, you create a BasedOn style BasedOn style (this is what this constructor does), then you add a trigger and change the style link of your button to a new style. When you delete, you create a new style, again based on the style that your button refers to, remove the trigger from its collection of triggers , which will do nothing because the collection is empty , and then reassign this style.

No, that, of course, won't work.

Edit: Create a basic style as a read link, then when these dynamic triggers need to be added or removed, create a new style based on your link and recreate all the triggers iterating over your -collection trigger.

+1
source

Source: https://habr.com/ru/post/893526/


All Articles