簡體   English   中英

WPF-ListBoxItem-動態更改DataTemplate元素的顏色

[英]WPF - ListBoxItem - Change DataTemplate element colors dynamically

有幾篇有關此任務的文章。 但是,似乎沒有一個足夠接近我所做的工作。 我有一個自定義控件,其模板中有一個ListBox。 我已經按照自己的喜好重新整理了ListBox的模板。 選擇一個項目后,我想更改顏色。 這是我的問題似乎向大多數其他人發散的部分:我不知道什么顏色。 它是要渲染的項目中的任何顏色。 我在XAML中綁定了不同的顏色,但是在設置新顏色時它不會重繪。 我更改了項目中的默認顏色,以確保模板首先選擇了正確的值。 那成功了。 我嘗試過的事情:綁定,讓項目實現INotifyPropertyChanged和帶有Storyboard的EventTrigger(我認為這從來沒有真正構建過,因為我的價值不是靜態資源)。 我在這里錯過了一些非常基本的東西。 我確定。 以下是代碼摘錄以幫助您:

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>

助手類:

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);
    }
};

任何幫助將非常感激。

好的,您可以在SomeItem而不是在MultiStateSelectionGridState實現INPC,因此,在切換狀態時,您需要創建一個新的CurrentState對象,而不是像CurrentState.Background = "Blue";這樣的東西CurrentState.Background = "Blue"; 在代碼背后

您還需要切換

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

OnPropertyChanged(new PropertyChangedEventArgs("CurrentState"));

現在,當您切換CurrentState變量時(選中項目時),該變量將傳播到View並相應地查詢其屬性。

我通過執行以下操作對此進行了測試:

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

你可以在這里找到一個可行的例子

如果不想繼續為狀態更改而重新創建CurrentState對象,則使MultiStateSelectionGridState實現INPC本身。

邊注

我不知道您實際在哪里或何時知道要為控件設置的顏色,因此無法建議如何將其移動到xaml。 但是您應該考慮讓它們來自xaml

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM