Привязка фона элемента ListBox к определенному значению - PullRequest
2 голосов
/ 11 октября 2010

Я скорее новичок в WPF и все еще играю с привязками и прочим, так что это, вероятно, основной вопрос.

Рассмотрим следующий класс:

class DataHolder
{
    public List<int> Data;

    // Points to one of the items in Data. Thus can be between 0 and Data.Count
    public int Pointer;
}

Я установил DataContext в ListBox как экземпляр вышеупомянутого класса, а его ItemSource - это «Данные» экземпляра.

Теперь я хотел бы отметить в ListBox цвет элемента списка, который содержит Data [Pointer] , чтобы быть серым цветом.

Что я должен использовать? Я пытался сделать это с DataTriggers, но я не уверен, как сравнить два разных значения, используя их. Я бы предпочел не использовать IValueConverter на этом этапе, если это невозможно сделать иначе.

РЕДАКТИРОВАТЬ: не стесняйтесь преобразовывать открытые данные в свойства в указанном классе

Спасибо!

Ответы [ 3 ]

2 голосов
/ 11 октября 2010

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

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">

<Window.DataContext>
    <local:MainWindow_ViewModel/>
</Window.DataContext>
<StackPanel>
    <TextBox Text="{Binding Pointer, Mode=TwoWay}" Height="20" Width="100"/>
    <ListBox ItemsSource="{Binding MyDataHolder}" Height="20" Width="100">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Value}" Background="{Binding Color}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>

MainWindow_ViewModel.cs

public class MainWindow_ViewModel
{
    public MainWindow_ViewModel() 
    {
        data = new DataHolder();

        foreach (int value in data.Data)
        {
            myData.Add(new Data_DataViewModel() { Value = value });
        }

        this.Pointer = 4;
    }

    private DataHolder data;
    private List<Data_DataViewModel> myData = new List<Data_DataViewModel>();

    public List<Data_DataViewModel> MyDataHolder
    {
        get
        {
            return myData;
        }
    }

    public int Pointer
    {
        get { return this.data.Pointer; }
        set 
        {
            this.data.Pointer = value;
            foreach (Data_DataViewModel dvm in this.myData)
            {
                dvm.UpdateColor(this.data.Pointer);
            }
        }
    }
}

DataHolder.cs

public class DataHolder
{
    public List<int> Data
    {
        get { return data; }   
    }
    private List<int> data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };

    public int Pointer = 3;
}

Data_DataViewModel.cs

public class Data_DataViewModel : INotifyPropertyChanged
{
    public int Value
    {
        get { return val; }
        set { val = value; } 
    }
    private int val;

    public Brush Color
    {
        get 
        {
            if (this.Value == pointer)
            {
                return Brushes.Gray;
            }
            else
            {
                return Brushes.Pink;
            }
        }
    }

    private int pointer;

    public void UpdateColor(int pointerValue)
    {
        this.pointer = pointerValue;
        OnPropertyChanged("Color");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
1 голос
/ 12 октября 2010

В списке также есть свойство SelectedIndex , к которому можно привязаться.Сделайте индекс свойством для вашей ViewModel (Подсказка: свойство data, также убедитесь, что свойство запускает событие уведомление об изменении ).Затем отредактируйте Выбранное состояние элемента списка.

ИМО намного проще, чем другие предложения, и использует шаблон и привязку more соответствующим образом.

1 голос
/ 12 октября 2010

Интересный вопрос. Мое решение использует ItemTemplateSelector. В переопределении SelectTemplate вы можете получить доступ к Panel (VirtualizingStackPanel), в которой размещены элементы ListItems. Хитрость в том, что при добавлении каждого ListItem в ListBox вызывается это переопределение, и мы можем использовать ChildCount для определения его индекса в ListBox. Это помогает нам в сравнении и выборе правильного шаблона.

Main.xaml

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" x:Class="WpfApplication1.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>       
        <DataTemplate
            x:Key="DataTemplateWithHighlight">
            <StackPanel>
                <TextBlock HorizontalAlignment="Stretch"
                    Text="{Binding Mode=OneWay}"
                    Background="Gray" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate
            x:Key="DataTemplateWithoutHighlight">
            <StackPanel>
                <TextBlock
                    HorizontalAlignment="Stretch"
                    Text="{Binding Mode=OneWay}"
                    Background="White" />
            </StackPanel>
        </DataTemplate>
        <local:ListBoxItemTemplateSelector
            x:Key="listBoxItemTemplateSelector"
            HighlightedItemTemplate="{StaticResource DataTemplateWithHighlight}"
            NonHighlightedItemTemplate="{StaticResource DataTemplateWithoutHighlight}" />

    </Window.Resources>
    <StackPanel Orientation="Vertical" d:LayoutOverrides="Height" HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListBox
            x:Name="listBoxWithMeaninglessNumbers"
            Height="100"
            Width="100"
            ItemsSource="{Binding Data}"
            ItemTemplateSelector="{DynamicResource listBoxItemTemplateSelector}">          
        </ListBox>
    </StackPanel>
</Window>

Класс DataItems

 public  class DataItems
    {
      public List<int> Data { get; set;}
      public int HighlightedIndex { get; set; }
    }

Некоторые исходные данные, которые помогут вам начать работу

public static class DataStub
{
        public static DataItems TestDataItems
        {
            get
            {
                var dataItems = new DataItems();
                dataItems.Data = new List<int>(){1,5,9,6,8};
                dataItems.HighlightedIndex = 2;

                return dataItems;
            }
        }
}

MainWindow.xaml.cs

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        listBoxWithMeaninglessNumbers.DataContext = DataStub.TestDataItems;
    }
}

TemplateSelector Class:

 public class ListBoxItemTemplateSelector:DataTemplateSelector
    {
       public DataTemplate NonHighlightedItemTemplate { get; set; }
       public DataTemplate HighlightedItemTemplate { get; set; }



         public override DataTemplate SelectTemplate(object item, DependencyObject container)
       {
             var listBoxItem = ((FrameworkElement) container).TemplatedParent as ListBoxItem;
             var panel = VisualTreeHelper.GetParent(listBoxItem) as Panel;
             var highlightedIndex = (panel.DataContext as DataItems).HighlightedIndex;
             var currentChildIndex = panel.Children.Count-1;

             return (highlightedIndex == currentChildIndex) ? HighlightedItemTemplate : NonHighlightedItemTemplate;
            }
    }
}

Надеюсь, это поможет.

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