2013-04-25 2 views
0

Существует несколько статей, посвященных подобным задачам. Тем не менее, ничто не кажется достаточно близким, чтобы работать на то, что я делаю. У меня есть настраиваемый элемент управления, который имеет ListBox в своем шаблоне. Я переработал шаблон для ListBox по своему вкусу. Когда элемент выбран, я хочу изменить цвет. Вот та часть, где моя проблема, по-видимому, расходится с большинством других: я не знаю, какой цвет. Это то, что цвет в обрабатываемом элементе. Я связал разные цвета в XAML, но он не перерисовывается, когда я устанавливаю новый цвет. Я изменил цвет по умолчанию в элементах, чтобы убедиться, что вначале шаблон подбирал правильные значения. Это удалось. Вещи, которые я пробовал: привязка, когда элементы реализуют INotifyPropertyChanged и EventTrigger со Storyboard (который никогда не строился, я предполагаю, потому что мое значение не было статическим ресурсом). Мне здесь не хватает чего-то очень элементарного. Я уверен. Вот код выдержки, чтобы помочь:WPF - ListBoxItem - динамически меняет цвета элементов DataTemplate

XAML:

<Setter Property="ItemTemplate"> 
    <Setter.Value> 
     <DataTemplate> 
      <Border BorderBrush="{Binding CurrentState.Border}" BorderThickness="1"> 
       <TextBlock Text="{Binding DisplayObject}" Foreground="{Binding CurrentState.Foreground}" Background="{Binding CurrentState.Background}" MinHeight="12" MinWidth="50" Padding="2" ToolTip="{Binding ToolTip}"/> 
      </Border> 
     </DataTemplate> 
    </Setter.Value> 
</Setter> 

классы Helper:

public class MultiStateSelectionGridState 
{ 
    public string Background { get; set; } 
    public string Foreground { get; set; } 
    public string Border { get; set; } 
    public string Text { get; set; } 

    public MultiStateSelectionGridState() 
    { 
     Background = "White"; 
     Foreground = "Black"; 
     Border = "Black"; 
     Text = String.Empty; 
    } 
}; 

public interface IMultiStateSelectionGridItem : INotifyPropertyChanged 
{ 
    object DisplayObject { get; } 
    object ToolTip { get; } 
    object Value { get; } 
    MultiStateSelectionGridState CurrentState { get; set; } 
    void OnPropertyChanged(PropertyChangedEventArgs e); 
}; 

Я не знаю, сколько из класса элемента я могу опубликовать, поэтому я не буду делать так изначально. Это выглядит следующим образом:

class SomeItem : IMultiStateSelectionGridItem 
{ 
    public int SomeInt { get; set; } 
    public string SomeString { get; set; } 
    public string SomeOtherString { get; set; } 

    public object DisplayObject 
    { 
     get { return SomeString + CurrentState.Text; } 
    } 

    public object ToolTip 
    { 
     get { return SomeOtherString; } 
    } 

    public object Value 
    { 
     get { return SomeInt; } 
    } 

    private MultiStateSelectionGridState m_currentState; 

    public MultiStateSelectionGridState CurrentState 
    { 
     get 
     { 
      return m_currentState; 
     } 

     set 
     { 
      m_currentState = value; 
      //Notice that this was just test code and I tried CurrentState, Background, and what 
      //you see there now. 
      OnPropertyChanged(new PropertyChangedEventArgs("CurrentState.Background")); 
     } 
    } 

    public SomeItem() 
    { 
     SomeInt = 0; 
     SomeString = String.Empty; 
     SomeOtherString = String.Empty; 
     CurrentState = new MultiStateSelectionGridState(); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, e); 
    } 
}; 

Любая помощь будет очень признательна.

+0

Во-первых, я не поклонник ссылок на Цвета в коде и скорее предпочитаю держать их в xaml в моих лучших проявлениях. Это даже прекрасно для вас?Также исправлюсь ли я в предположении, что вам нужен только этот динамический цвет, применяемый при выборе элемента? – Viv

+0

Если бы я знал, какие цвета, все будет хорошо. Я пытаюсь сделать это очень гибким. И короткий ответ заключается в том, что я делаю то, что он применяет при отборе. Я меняю то, что выбрал, после того, как я переберу этот горб, но я хочу, чтобы цвет менялся при выборе. Вероятно, стоит отметить, что, хотя я изменяю цвет на конкретный, в примере, который является просто заполнителем, @Viv. – BillyD

ответ

0

Ok ваши реализации INPC в SomeItem и не MultiStateSelectionGridState поэтому при переключении состояния необходимо в значительной степени создать новый объект CurrentState, чем идти что-то вроде CurrentState.Background = "Blue"; в коде-за

Кроме того, необходимо переключить

OnPropertyChanged(new PropertyChangedEventArgs("CurrentState.Background")); 

в

OnPropertyChanged(new PropertyChangedEventArgs("CurrentState")); 

Теперь, когда вы переключаете CurrentState переменная (когда элемент выбран), он будет распространяться на представление, и его свойства будут запрошены соответствующим образом.

Я проверил это, делая что-то вроде:

Items = new ObservableCollection<SomeItem> { 
    new SomeItem { 
    CurrentState = new MultiStateSelectionGridState() 
    } 
}; 

// Simulating a Selected State change 
var tempTask = new Task 
    (
() => { 
    Thread.Sleep(5000); 
    Items[0].CurrentState = new MultiStateSelectionGridState { 
     Background = "Green", 
     Border = "Blue" 
    }; 
    }, 
    TaskCreationOptions.LongRunning 
); 
tempTask.Start(); 

и имеющий ListBox есть это ItemsSource, как Items сверху.

Вы можете найти рабочий пример этого Here

Если вы не хотите, чтобы воссоздать CurrentState объект для изменения состояния, сделать MultiStateSelectionGridState реализовать сам INPC.

Побочное примечание

Я не знаю, где и когда вы на самом деле узнать, что цвета, чтобы установить для контроля, так косяк советуют, как двигаться, что XAML. Но вы должны смотреть на то, чтобы они исходили из xaml.

+0

Я мог бы просто кричать прямо сейчас. Я знал, что это будет что-то простое. Он работает сейчас. Спасибо за помощь! – BillyD

Смежные вопросы