Правильный способ удалить триггер - PullRequest
6 голосов
/ 26 июля 2011

Я работаю с формой, где некоторые 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;
    }

Но, похоже, это не сработает - если триггер удален, пока он активен, то кнопка остается отключенной.

У меня былоПредполагается, что кнопка будет переоценивать свой стиль всякий раз, когда ему дается новый.кажется, что это происходит при добавлении триггера, но не при его удалении - что мне здесь не хватает?

РЕДАКТИРОВАТЬ: Изменен код для добавления / удаления триггеров в соответствии с рекомендациями в Комментарий HB .Тем не менее, рассматриваемая проблема остается.

РЕДАКТИРОВАТЬ 2: * В конце концов, возможно, не так хорошо - я попытался добавить дополнительный ComboBox (и триггер) и обнаружил, что добавлениевторой триггер, кажется, сломает первый.Используя этот код, работает только последний добавленный триггер.Должен ли я думать о триггерах FrameworkElement как о коллекции с однократной записью и искать другой способ достижения такого поведения?

Ответы [ 2 ]

1 голос
/ 27 января 2012

Прошло много времени с тех пор, как был задан этот вопрос, но я подумал, что хотя бы напишу, как решил проблему для того, чтобы поделиться:

Я так и не нашел способ удалить триггеры, которые работали бы надежно. Поэтому вместо этого я добавил в свой вид свойство, которое указывало бы, как все триггеры оценивали бы, если бы они существовали, и подключил DataTrigger к этому свойству.

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

Вместо добавления и удаления триггеров создали обработчики для просмотра свойств, которые триггеры наблюдали бы:

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

Это избавляет от всех хлопот с созданием и удалением триггеров. Вместо этого есть один триггер, и добавление и удаление обработчиков событий работает просто отлично.

(Хаки, да.)

1 голос
/ 26 июля 2011

Таким образом, вы создаете стиль BasedOn стиль MyButton (это то, что делает этот конструктор), затем вы добавляете триггер и изменяете ссылку стиля вашей кнопки на ваш новый стиль. При удалении вы создаете новый стиль, опять же на основе стиля, на который в данный момент ссылается ваша кнопка, удаляете триггер из его коллекции триггеров , который ничего не будет делать, поскольку коллекция пуста , а затем снова назначаете этот стиль.

Нет, это, конечно, не сработает.

Редактировать: Создать базовый стиль как ссылку только для чтения, затем, когда эти динамические триггеры необходимо добавить или удалить, создайте новый стиль на основе вашей ссылки и заново создайте все триггеры, повторяя итерацию по вашему триггеру. коллекция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...