我正在使用一个表单,可以通过编程方式创建和删除一些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的触发器视为一次写入集合并找到实现此类行为的不同方法?
答案 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,是的。)