【问题标题】:Proper way to remove a Trigger删除触发器的正确​​方法
【发布时间】:2011-07-25 20:46:23
【问题描述】:

我正在使用一种可以通过编程方式创建和删除某些 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 从窗口中删除时该怎么办。我需要从按钮的样式中删除触发器,因为我不再希望 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 的触发器视为一次写入的集合并找到一种不同的方法来实现这种行为?

【问题讨论】:

  • 如果Button被移除,Trigger不会同时被移除吗?

标签: c# wpf


【解决方案1】:

因此,您创建了BasedOn 的样式MyButton 的样式(这就是这个构造函数所做的),然后添加触发器并将按钮样式的引用更改为新样式。在删除过程中,您创建一个新样式,再次基于按钮当前引用的样式,从其触发器集合中移除触发器.

不,这当然行不通。

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

【讨论】:

  • 啊哈,我错过了基于现有样式创建样式不会复制其触发器集合。但是,问题依然存在——新的 Style 仍然没有包含我要删除的触发器,那么为什么 Trigger 似乎仍然有影响?
  • @SeanU:确实,我认为这可能是您的假设,所以刚才我在您发表评论时添加了一个附加说明。
  • 谢谢,我现在正在解决这个问题,但我在您编辑时添加了一个问题。必须有一些解决方案,因为不允许直接编辑 MyButton.Style。
  • @SeanU:创建一个基本样式作为只读引用,然后在添加或删除触发器时基于该样式创建一个新样式,并通过迭代您的触发器集合重新创建所有触发器。跨度>
  • @HB:刚刚完成了这一点,并且即将更新我的示例代码以反映它。它不起作用。该按钮保持禁用状态。
【解决方案2】:

这个问题被问到已经很久了,但我想我至少应该发布一下我是如何解决这个问题的,以便分享:

我从来没有找到移除可靠工作触发器的方法。因此,我向我的视图添加了一个属性,该属性指示所有触发器将如何评估(如果它们存在),并将DataTrigger 与此属性挂钩。

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

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

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

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

(哈克,是的。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-19
    • 2015-07-18
    • 2017-07-24
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多