正确的方法来删除触发器

时间:2011-07-25 20:46:24

标签: c# wpf

我正在使用一个表单,可以通过编程方式创建和删除一些ComboBox。

创建它们时,会创建一些以它们为目标的触发器并将其应用于按钮:

    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;
    }

到目前为止这么好*。 。 。问题是,从窗口中删除ComboBox时该怎么办。我需要从按钮的Style中删除触发器,因为我不再希望ComboBox影响它的行为。我尝试了最明显的选择:

    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;
    }

但是这似乎不起作用 - 如果触发器在激活时被移除,则按钮保持禁用状态。

我曾假设按钮会在给出新样式时重新评估其样式。添加触发器时似乎会发生这种情况,但是当它被移除时却不会发生 - 我在这里缺少什么?

编辑:根据H.B.'s comment中的建议更改了添加/删除触发器的代码。但是,问题仍然存在。

编辑2: *毕竟可能不是那么好 - 我继续尝试添加额外的ComboBox(和触发器)并发现添加第二个触发器似乎打破了第一个触发器。使用此代码,只有最近添加的触发器才有效。我是否应该将FrameworkElement的触发器视为一次写入集合并找到实现此类行为的不同方法?

2 个答案:

答案 0 :(得分:1)

因此,您创建样式BasedOn MyButton的样式(这就是此构造函数的作用),然后添加触发器并将按钮样式的引用更改为新样式。在删除中,您再次根据按钮当前引用的样式创建一个新样式,从其触发器集合中删除一个触发器,该触发器集合为空时不会执行任何操作,然后再次重新分配此样式

不,这当然行不通。

编辑:创建基本样式作为只读引用,然后在添加或删除这些动态触发器时,根据引用创建新样式,并在迭代触发器时重新创建所有触发器-collection。

答案 1 :(得分:1)

自问这个问题以来已经很长时间了,但我想我至少会发布一下为了分享而解决问题的方法:

我从未找到过删除可靠工作的触发器的方法。所以相反,我在我的View中添加了一个属性,该属性指示了所有触发器如何评估(如果它们已存在),并将DataTrigger挂钩到此属性。

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

代替添加和删除触发器,创建了一个处理程序来监视触发器将要监视的属性:

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

这可以避免创建和删除触发器的所有麻烦。相反,有一个触发器,添加和删除事件处理程序工作得很好。

(Hacky,是的。)