Shingo Tada
Shingo Tada

Reputation: 571

How to change Foreground color of TextBlock in DataTemplate from code on Windows Phone?

I'd like to change Foreground color of TextBlock (bellow TitleText and DateText) in DataTemplate from code.

<ListBox x:Name="listBox1" ItemsSource="{Binding}" ScrollViewer.ManipulationMode="Control" SelectionChanged="listBox1_SelectionChanged">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel x:Name="stackPanel1" HorizontalAlignment="Stretch" Orientation="Horizontal">
                <TextBlock FontSize="35" x:Name="TitleText" Text="{Binding Title}" Width="386" Foreground="Black" />
                <TextBlock FontSize="25" x:Name="DateText" Text="{Binding Date}" Width="78" Foreground="Black" />
                <TextBlock x:Name="Id" Text="{Binding Id}" Visibility="Collapsed" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

I'd like to do like this in code behind. But It seems not be able to access x:Name property in DataTemplate.

this.TitleText.Foreground = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0);

Does anyone know a good solution for this ?

Upvotes: 1

Views: 5500

Answers (4)

Shingo Tada
Shingo Tada

Reputation: 571

MyKuLLSKI gave me perfect solution. But I couldn't make it.

I was struggling and I found my problem. I wrote the answer (only for me ) in my blog. Please take a glance it.

Cannot bind two types of data source to one UI target http://myprogrammingdial.blogspot.com/2012/03/cannot-bind-two-types-of-data-source-to.html

Upvotes: -1

MyKuLLSKI
MyKuLLSKI

Reputation: 5325

Why don't you do it the Fast way instead of crawling the Visual Tree.

<TextBlock FontSize="35" Text="{Binding Title}" Width="386" Foreground="[Binding Color}" />

Then all you have to do is:

  1. Add a Color Brush Property in your Collection
  2. Change this property to the color you want
  3. Make sure this property implement INotify or is a Dependency Property

Example

XAML

<Grid>
    <ListBox ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
                    <TextBlock Text="{Binding Title}" Foreground="{Binding TitleColor}" />
                    <TextBlock Text="{Binding Date}" Foreground="Black" />
                    <TextBlock Text="{Binding Id}" Visibility="Collapsed" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

CodeBehind

public partial class MainPage : Page
{
    public ObservableCollection<TEST> TestCollection { get; private set; }

    public MainWindow()
    {
        InitializeComponent();

        TestCollection = new ObservableCollection<TEST>();
        TestCollection.Add(new TEST()
        {
            TitleColor = Brushes.Black,
            ID = 0,
            Title = "A",
            Date = DateTime.Now,
        });

        TestCollection.Add(new TEST()
        {
            TitleColor = Brushes.Red,
            ID = 1,
            Title = "B",
            Date = DateTime.Now.AddDays(1),
        });

        DataContext = TestCollection;
    }
}

public class TEST : INotifyPropertyChanged
{
    private Brush _TitleColor;
    public Brush TitleColor
    {
        get
        {
            return _TitleColor;
        }

        set
        {
            _TitleColor = value;
            OnPropertyChanged("TitleColor");
        }
    }

    private int _ID;
    public int ID
    {
        get
        {
            return _ID;
        }

        set
        {
            _ID = value;
            OnPropertyChanged("ID");
        }
    }

    private string _Title;
    public string Title
    {
        get
        {
            return _Title;
        }

        set
        {
            _Title = value;
            OnPropertyChanged("Title");
        }
    }

    private DateTime _Date;
    public DateTime Date
    {
        get
        {
            return _Date;
        }

        set
        {
            _Date = value;
            OnPropertyChanged("Date");
        }
    }

    public TEST()
    {
    }

    #region INotifyProperty
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    #endregion
}

Upvotes: 6

ZombieSheep
ZombieSheep

Reputation: 29963

To Expand on MyKuLLSKI's answer, if your change is based on some value already in your object (eg. an int property that is greater than 5), you could use a ValueConverter (see here for an example) to read the value and return a brush. That is cleaner than adding a colour to your model since it is (arguably) UI related rather than data related.

Upvotes: 0

Ku6opr
Ku6opr

Reputation: 8126

You can use FindItem method to find element in visual tree by it name and then change it Foregorund.

((listBox.ItemContainerGenerator.ContainerFromIndex(5) as FrameworkElement).FindName("TitleText") as TextBlock).Foreground = new SolidColorBrush(Color.FromArgb(255, 128, 128, 128));

where 5 is your item index

Upvotes: 1

Related Questions