4

Вот сделка. Я могу создать ListBox и создать его. Я могу отредактировать копию шаблона, чтобы государства стали доступны в Expression Blend 3. И я могу изменить состояние так, чтобы цвет фона в позиции был изменен при выборе. Но я не могу изменить цвет переднего плана текста из-за ContentPresenter! Есть ли у кого-нибудь пример XAML, который показывает, как выполнить эту, казалось бы, легкую задачу?Как я могу использовать VisualStateManager для изменения цвета текста (переднего плана) ListBoxItem?

Ответ, похоже, заключается в удалении ContentPresenter и замене его каким-то стилем или шаблоном ListBoxItem, но это то место, где я застреваю. ContentPresenter ListBox ссылается на какой-то другой шаблон «TemplateBinding Template» - где это? Кроме того, когда я пытаюсь каким-либо образом модифицировать ContentPresenter, панель «Штаты» пуста, и я остаюсь с болотом XAML. К счастью, есть CTRL-Z!

Я действительно считаю, что Microsoft должна пересмотреть подход XAML или сделать Blend более полным инструментом. Способ, которым он должен работать, заключается в том, что я должен иметь возможность нажимать на ЛЮБОЙ элемент и определять для него состояния. Если я пытаюсь нарушить правила, Blend должен сказать мне это и предложить способ исправить это. Просто, когда панель «Штаты» пуста, это не помогает.

ответ

1

Обычно ListBox является не ответственности за содержание самих изделий, включая то, что Foreground цвета, в случае необходимости, они используют. Элементами могут быть серии изображений, и в этом случае Foreground не имеет смысла. Элементы могут представлять собой сложный многоэлементный пользовательский интерфейс, содержащий различные текстовые элементы, каждый из которых нуждается в разных цветах, поэтому идея ListBox, поставляющая один цвет Foreground, не имеет смысла.

Именно поэтому шаблон по умолчанию для контейнера Item использует ContentPresenter, что в основном означает «разместить здесь содержимое субординированного элемента».

Если вы хотите создать новый стиль для списков в целом для использования в своих стилях элементов контейнера, вам придется принять это ограничение, ваш VSM не сможет узнать детали содержащегося элемента.

Однако, если вы создаете стиль контейнера для определенного экземпляра ListBox, и вы понимаете тип и характер представленных предметов, вам не нужно хранить ContentPresenter в шаблоне. Вы можете напрямую заменить то, что когда-либо Xaml вам нужно представить каждый элемент.

Например, вы могли бы заменить ContentPresenter в Xaml с этим: -

<Grid Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"> 
    <TextBlock x:Name="ContentItem" Text="{Binding Property1, Mode=OneWay}" TextWrapping="Wrap" Foreground="#FFDC1C1C"/> 
</Grid> 

Обратите внимание, что Перетяжка и HorizontalAlignment из элементов такие же, как те, которые используются предъявителю. В этом случае я использую как одиночный TextBlock под названием «ContentItem» и привязывая его к исходным объектам Property1.

Теперь, когда шаблон содержит имя TextBlock для отображения элемента, я могу поиграть с VSM, чтобы изменить его Foreground для различных различных состояний Visual.

+0

Я заменил ContentPresenter специальным DataTemplate, состоящим из пользовательского элемента управления. Этот элемент управления имеет текстовый блок. Для работы VSM мне как-то нужно получить ссылку на фактический экземпляр управляющего элемента, когда listbox вызывает событие SelectionChanged. Это проблематично. Для метода VSM.GoToState необходимо передать экземпляр, чтобы он мог работать. Кажется, я не могу получить ссылку. Идеи? Я согласен, что вы должны иметь возможность «возиться с vsm», чтобы сделать эту работу, но должно быть оптимальным словом, здесь. Но я все равно не вижу, чтобы кто-нибудь это делал. – Wade

+0

Теперь я могу захватить каждый пользовательский экземпляр DataTemplate в массив во время события Loaded элемента управления, а затем использовать числовые индексы, чтобы найти экземпляр, основанный на родительском свойстве SelectedIndex ListBox, но это вряд ли масштабируется. – Wade

+0

Ну, я нашел способ сделать это без использования VSM, но это исключает возможность воспроизведения анимаций. Я изменил на Foreground текстового блока на {TemplateBinding Foreground}, а затем установил Foreground в ListBoxItem. Вздох .... – Wade

1

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

Это очень просто: если вы замените ContentPresenter в своем шаблоне ContentControl, то он будет работать (ContentControl имеет свойство Foreground).

0

Ах, круто! Спасибо за ответ. Я думаю, что я закончил тем, что сделал пользовательский контроль и выставил публичное свойство Foreground, которое установило цвет, но я не могу вспомнить. Ваш ответ в сочетании с предыдущим очень полезен.

В отставке я сломался и научился создавать собственные пользовательские элементы управления с зависимыми свойствами и целыми 9 ярдами, и, как мне кажется, это стоило того. Я чувствую, что теперь могу сделать что-либо с WPF/SL.