В WPF я могу вручную «сбросить» или повторно протестировать триггеры для стиля? - PullRequest
3 голосов
/ 21 июня 2011

То, что я хочу сделать, это повторно протестировать Trigger при возникновении события.Это связано с тем, что Trigger связывается со свойством Row.RowState DataRowView, которое НЕ запускает уведомление PropertyChanged, требующее триггера for для повторной оценки его состояния.

(см.сообщение в нижней части этой страницы: WpfToolkit DataGrid: выделение измененных строк )

Я могу переустановить Trigger для каждого элемента управления в случае, подобном этому:

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        Style s = ((TextBox)sender).Style;
        ((TextBox)sender).Style = null;
        ((TextBox)sender).Style = s;
    }

Но у меня есть DataGrid со многими элементами управления, и все они используют один из четырех Style с.Что я хотел бы сделать, это сделать что-то вроде, в коде псевдо:

Style1.reTest();
Style2.reTest();
...

Есть ли способ сделать это?Первая проблема заключается в том, что вы не можете назвать стили, поэтому доступ к ним из xmlns является проблематичным.Вторая проблема заключается в том, что Style не имеет метода, который обеспечивает эту функциональность.

Любая помощь, наиболее подходящая для использования.

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

Style s = (Style)Resources[typeof(System.Windows.Controls.TextBox)];

Edit2: я нашел ответ и опубликую его, когда Stackoverflow позволит мне это сделать.Большое спасибо за все ответы:)

Фугу

Ответы [ 3 ]

1 голос
/ 21 июня 2011

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

Другой вариант - добавить дополнительный столбец в таблицу DataTable для хранения состояния строки.Всякий раз, когда изменяется состояние строки, вы обновляете это значение.В вашей DataGrid вы скрываете этот дополнительный столбец, но теперь он доступен для привязки к DataTrigger

Редактировать: подробное объяснение опции №2

DataTable myTable
myTable.Columns.Add("Foo");
//etc etc
myTable.Columns.Add("INTERNAL_STATUS",typeof(DataRowState));


//Attach event handlers to DataTable.RowChanged, DataTable.ColumnChanged, etc
//I will just show RowChanged here

    private void Row_Changed(object sender, DataRowChangeEventArgs e)
        {
                e.Row["INTERNAL_STATUS"] = e.Row.RowState;
        }

//Now in your XAML you can use the INTERNAL_STATUS in your data trigger
0 голосов
/ 21 июня 2011

Сделал это!

Допустим, у вас есть несколько стилей в вашем XAML, у которых нет имен (потому что вы хотите, чтобы они применялись ко всем элементам управления определенного типа).

Выполнитеэто для сброса / переоценки триггеров и замены TextBox на соответствующий тип:

        Style s = (Style)Resources[typeof(System.Windows.Controls.TextBox)];
        Resources[typeof(System.Windows.Controls.TextBox)] = null;
        Resources[typeof(System.Windows.Controls.TextBox)] = s;

Может быть, это будет быстрее сделать то же самое для триггеров вместо всего стиля, мне нужно было бы проверить это какдля добавления триггеров обратно в TriggersCollection потребуется цикл (так что, вероятно, это не так быстро).

Если у вас есть имена стилей, ключом является имя в виде строки, а не тип стиляотносится к.

Если вы хотите выделить строки в DataGrid при их изменении, вы можете вставить приведенный выше код в событие.

0 голосов
/ 21 июня 2011

Настройка TargetName должна работать, однако она не может работать в стиле.Если вы думаете об этом, это имеет смысл: если вы установите целевое имя в стиле, в какой области во время выполнения нужно искать это имя?Таким образом, вы можете попытаться установить имя цели, но не в стиле, а в триггерах самого элемента.

...