Добавить элементы в список и стиль - PullRequest
0 голосов
/ 11 августа 2011

У меня есть простой класс:

public class Foo
{
    public string Text { get; set; }
    public bool AppleStyle { get; set; }

    public Foo(string text, bool applyStyle)
    {
        Text = text;
        ApplyStyle = applyStyle;
    }

    public override string ToString()
    {
        return Text;
    }
}

, который затем используется для добавления элементов в ListBox:

var one = new Foo("Some Text", false);
var two = new Foo("More Text", true);
MyListBox.Items.Add(one);
MyListBox.Items.Add(two);

Затем я перебираю элементы в ListBox выяснить, как их стилизовать.Вот где я застреваю.Я попытался унаследовать от ListBoxItem для класса, но при этом не было добавлено ни одного элемента.

for (int i = 0; i < MyListBox.Items.Count; i++)
{
    if(((Foo)MyListBox.Items[i]).ApplyStyle)
    {
        ((ListBoxItem)MyListBox.Items[i]).Style = Resources["MyStyle"] as Style;        
    }
}

Обновление:
В MainWindow.xaml:

<Window.Resources>
    <Style x:Key="MyStyle" TargetType="ListBoxItem">
        <Setter Property="Background" Value="Bisque"></Setter>
        <Setter Property="FontWeight" Value="Bold"></Setter>
    </Style>
</Window.Resources>

Обновление 3:
Чтобы добиться определенного прогресса, нужно просто знать, как обновить стили (после нажатия на кнопку).Плюс, если Resource не находится в MainWindow.xaml, будет ли он выглядеть в App.xaml перед возвратом null?

MainWindow.xaml

<Window...>
    <Window.Resources>
        <Style x:Key="MyClass" TargetType="ListBoxItem">
            <Setter Property="Background" Value="Bisque"></Setter>
            <Setter Property="FontWeight" Value="Bold"></Setter>
        </Style>
        <myapp:MyListItemStyleSelector x:Key="MyListItemStyleSelector" />
    </Window.Resources>
    <Grid>
    ...
        <ListBox .... ItemContainerStyleSelector="{StaticResource: MyListItemStyleSelector}" />
    ...
    </Grid>
</Window>

MyListItemStyleSelector.cs

public class MyListItemStyleSelector : StyleSelector
{
    public override Style SelectStyle(object item, DependencyObject container)
    {
        ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(container);
        int index = ic.ItemContainerGenerator.IndexFromContainer(container);
        Style applyStyle = null;
        var data = item as Foo;
        if (data != null && data.ApplyStyle)
        {
            applyStyle = ic.TryFindResource("MyStyle") as Style;
        }
        return applyStyle;
    }
}

Ответы [ 3 ]

1 голос
/ 11 августа 2011

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

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

Я бы посоветовал вам сделать следующее.

Вместо того, чтобы менять стиль вашего ListBoxItem, посмотрите, достаточно ли использовать DataTemplate. DataTemplate определяет, как отображается содержимое вашего ListBoxItem.

<DataTemplate TargetType="{x:Type Foo}">
 <!-- your visuals and controls here -->
</DataTemplate> 

Теперь, если вы хотите использовать разные шаблоны данных, вы можете использовать разные классы и создавать для них разные DataTemplates, или вы используете DataTemplateSelector

 public class FooTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;
            var mdl = item as Foo;
            if( mdl.AppleStyle )
                return element.FindResource("appleTemplate") as DataTemplate;
            return element.FindResource("normalTemplate") as DataTemplate;
        }
    }

Создайте этот шаблонный селектор в xaml и укажите его в своем списке

<myNs:FooTemplateSelector x:Key="fooTemplateSelector"/>

<Listbox DataTemplateSelector="{StaticResource fooTemplateSelector}"/>

теперь вам нужно создать 2 DataTemplate s appleTemplate * normalTemplate *, и вы сможете легко определить, какой шаблон данных использовать во флаконе селектора. Что автоматически делается в ListBox для вас.

Если вы действительно хотите изменить стиль ItemContainer, вы можете использовать ItemContainerStyleSelector , который работает аналогично DataTemplateSelector. Но я бы не стал это предлагать. Вы должны предоставить содержимое и оставить ListBoxItem как есть, только если вы хотите изменить дизайн (в данном случае цвет выделения и т. Д.), В противном случае это может сбить пользователя с толку или нарушить функциональность.

0 голосов
/ 11 августа 2011

Почему бы не сделать это в XAML?

<ListBox Name="MyListBox">
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ApplyStyle}" Value="True">
                    <Setter Property="Background" Value="Bisque" />
                    <Setter Property="FontWeight" Value="Bold" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.Resources>
</ListBox>

Но ваша общая проблема заключается в том, что ListBox.Items возвращает коллекцию объектов данных, а не элементов управления XAML.Чтобы получить элемент управления XAML, содержащий объект данных, вы должны сделать то, что предложил HB, и использовать MyListBox.ItemContainerGenerator.ContainerFromItem(dataObject), чтобы получить контейнер XAML для объекта данных.Просто убедитесь, что вы подождите, пока ItemContainerGenerator завершит рендеринг элементов, чтобы получить контейнер (я думаю, что у него есть свойство Status или событие StatusChanged, которое вы можете использовать ... это было давно, и я не могу вспомнить точнуюсинтаксис)

0 голосов
/ 11 августа 2011

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

Используйте ItemContainerGenerator:

((ListBoxItem)MyListBox.ItemContainerGenerator.ContainerFromIndex(i)).Style = Resources["MyStyle"] as Style;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...